Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zapytanie w specyficznej bazie danych
Forum PHP.pl > Forum > Bazy danych > MySQL
thudy
Witam!

Posiadam dość nietypowy układ tabel w bazie danych - dla uściślenia - jest to wtyczka do Worpress'a "formidable" - umożliwiająca generowanie formularzy. Dość duże możliwości zapisu i odczytu z bazy, ale ja potrzebuję czegoś nietypowego.
Generalnie chodzi mi o dwie tabele które mają następującą strukturę:

tabela "frm_items" posiadająca min. pola:
- id
- user_id
- name
- itd

oraz tabela "frm_item_metas"
- id
- meta_value
- field_id
- item_id

W polu meta_value przechowywane są różne wartości, powiązanie pomiędzy jedną a drugą tabelą jest na podstawie klucza obcego item_id pochodzącego z pierwszej tabeli.
I teraz tak, potrzebuję zsumować wartości z pola meta_value gdzie field_id = 92 - i z tym sobie poradziłem poleceniem:
  1. SELECT SUM(meta_value)AS suma
  2. FROM `frm_item_metas`
  3. JOIN `frm_items`
  4. ON frm_items.id = frm_item_metas.item_id
  5. WHERE `user_id` = 2
  6. AND `field_id` =92

Problem polega na tym, że potrzebuję zawęzić sumowanie w/g daty. Data natomiast znajduje się również w polu meta_value, ale pod identyfikatorem field_id = 88
Samo polecenie zawężające datę wygląda tak:
  1. SELECT meta_value
  2. FROM `frm_item_metas`
  3. WHERE `field_id` = 88
  4. AND `meta_value` < '2014-02-01'

Jak to razem pożenić ? Czy muszę użyć PHP żeby zrobić jakąć pętle, czy uda się za pomocą jednego polecenia - pomysły mi się skończyły, więc proszę o pomoc.

Pozdrawiam
ghost1511
A nie możesz złączyć zapytań operatorem:
  1. UNION
? I wtedy w kodzie po ID rozpoznać czego problem dotyczy?
thudy
Cytat(ghost1511 @ 19.02.2014, 08:31:56 ) *
A nie możesz złączyć zapytań operatorem:
  1. UNION
? I wtedy w kodzie po ID rozpoznać czego problem dotyczy?

Po złączeniu otrzymuje dwa wyniki, a ja chcę otrzymać tylko sumę meta_value gdzie field_id ma wartość 88
Myślałem, żeby najpierw wyciągnąć item_id spełniające warunki zakresu daty
  1. SELECT `item_id`
  2. FROM `frm_item_metas`
  3. JOIN `frm_items`
  4. ON frm_items.id = frm_item_metas.item_id
  5. WHERE `user_id` = 2
  6. AND `field_id` = 88
  7. AND `meta_value` < '2014-02-01'

A potem za pomocą funkcji/pętli php sumować po kolei
  1. SELECT meta_value
  2. FROM `frm_item_metas`
  3. WHERE `field_id` = 88
  4. AND `item_id` = wynik_poprzedniego_zapytania

Ale to nie jest chyba dobre rozwiązanie - generuje strasznie dużo zapytań.
ghost1511
albo ja nie dokładnie rozumiem problem ale SUM i GROUP BY powinny rozwiązać problem. Chyba że wygląda to jakoś inaczej może podaj jakieś przykładowe dane i wyniki jakie chciałbyś uzyskać? wink.gif
thudy
Tabela frm_items:
  1. <frm_items>
  2. <id>24</id>
  3. <form_id>7</form_id>
  4. <post_id>0</post_id>
  5. <user_id>2</user_id>
  6. <is_draft>0</is_draft>
  7. <updated_by>2</updated_by>
  8. </frm_items>
  9. <frm_items>
  10. <id>25</id>
  11. <form_id>7</form_id>
  12. <post_id>0</post_id>
  13. <user_id>2</user_id>
  14. <is_draft>0</is_draft>
  15. </frm_items>
  16. <frm_items>
  17. <id>6</id>
  18. <form_id>7</form_id>
  19. <post_id>0</post_id>
  20. <user_id>3</user_id>
  21. <is_draft>0</is_draft>
  22. </frm_items>
  23. <frm_items>
  24. <id>21</id>
  25. <form_id>7</form_id>
  26. <post_id>0</post_id>
  27. <user_id>2</user_id>
  28. <is_draft>0</is_draft>
  29. </frm_items>
  30. <frm_items>
  31. <id>22</id>
  32. <form_id>7</form_id>
  33. <post_id>0</post_id>
  34. <user_id>2</user_id>
  35. <is_draft>0</is_draft>
  36. </frm_items>
  37. <frm_items>
  38. <id>19</id>
  39. <form_id>7</form_id>
  40. <post_id>0</post_id>
  41. <user_id>2</user_id>
  42. <is_draft>0</is_draft>
  43. </frm_items>
  44. <frm_items>
  45. <id>18</id>
  46. <form_id>7</form_id>
  47. <post_id>0</post_id>
  48. <user_id>2</user_id>
  49. <is_draft>0</is_draft>
  50. </frm_items>

Tabela frm_item_metas wygląda tak
  1. <frm_item_metas>
  2. <id>128</id>
  3. <meta_value>Orbitrek</meta_value>
  4. <field_id>87</field_id>
  5. <item_id>20</item_id>
  6. </frm_item_metas>
  7. <frm_item_metas>
  8. <id>259</id>
  9. <meta_value>0</meta_value>
  10. <field_id>96</field_id>
  11. <item_id>29</item_id>
  12. </frm_item_metas>
  13. <frm_item_metas>
  14. <id>214</id>
  15. <meta_value>668</meta_value>
  16. <field_id>100</field_id>
  17. <item_id>19</item_id>
  18. </frm_item_metas>
  19. <frm_item_metas>
  20. <id>213</id>
  21. <meta_value>140</meta_value>
  22. <field_id>97</field_id>
  23. <item_id>19</item_id>
  24. </frm_item_metas>
  25. <frm_item_metas>
  26. <id>212</id>
  27. <meta_value>8.5</meta_value>
  28. <field_id>96</field_id>
  29. <item_id>19</item_id>
  30. </frm_item_metas>
  31. <frm_item_metas>
  32. <id>211</id>
  33. <meta_value>50</meta_value>
  34. <field_id>92</field_id>
  35. <item_id>19</item_id>
  36. </frm_item_metas>
  37. <frm_item_metas>
  38. <id>129</id>
  39. <meta_value>2014-02-05</meta_value>
  40. <field_id>88</field_id>
  41. <item_id>20</item_id>
  42. </frm_item_metas>
  43. <frm_item_metas>
  44. <id>19</id>
  45. <meta_value>Orbi &amp; orbi</meta_value>
  46. <field_id>86</field_id>
  47. <item_id>6</item_id>
  48. </frm_item_metas>
  49. <frm_item_metas>
  50. <id>20</id>
  51. <meta_value>Ćwiczenia na orbitreku</meta_value>
  52. <field_id>87</field_id>
  53. <item_id>6</item_id>
  54. </frm_item_metas>
  55. <frm_item_metas>
  56. <id>21</id>
  57. <meta_value>2014-02-11</meta_value>
  58. <field_id>88</field_id>
  59. <item_id>6</item_id>
  60. </frm_item_metas>
  61. <frm_item_metas>
  62. <id>22</id>
  63. <meta_value>3</meta_value>
  64. <field_id>90</field_id>
  65. <item_id>6</item_id>
  66. </frm_item_metas>
  67. <frm_item_metas>
  68. <id>23</id>
  69. <meta_value>60</meta_value>
  70. <field_id>92</field_id>
  71. <item_id>6</item_id>
  72. </frm_item_metas>
  73. <frm_item_metas>
  74. <id>140</id>
  75. <meta_value>2</meta_value>
  76. <field_id>90</field_id>
  77. <item_id>21</item_id>
  78. </frm_item_metas>
  79. <frm_item_metas>
  80. <id>139</id>
  81. <meta_value>18:00</meta_value>
  82. <field_id>99</field_id>
  83. <item_id>21</item_id>
  84. </frm_item_metas>
  85. <frm_item_metas>
  86. <id>138</id>
  87. <meta_value>2014-02-06</meta_value>
  88. <field_id>88</field_id>
  89. <item_id>21</item_id>
  90. </frm_item_metas>
  91. <frm_item_metas>
  92. <id>137</id>
  93. <meta_value>Orbitrek</meta_value>
  94. <field_id>87</field_id>
  95. <item_id>21</item_id>
  96. </frm_item_metas>
  97. <frm_item_metas>
  98. <id>144</id>
  99. <meta_value>676</meta_value>
  100. <field_id>100</field_id>
  101. <item_id>21</item_id>
  102. </frm_item_metas>
  103. <frm_item_metas>
  104. <id>143</id>
  105. <meta_value>141</meta_value>
  106. <field_id>97</field_id>
  107. <item_id>21</item_id>
  108. </frm_item_metas>
  109. <frm_item_metas>
  110. <id>142</id>
  111. <meta_value>8.8</meta_value>
  112. <field_id>96</field_id>
  113. <item_id>21</item_id>
  114. </frm_item_metas>
  115. <frm_item_metas>
  116. <id>141</id>
  117. <meta_value>50</meta_value>
  118. <field_id>92</field_id>
  119. <item_id>21</item_id>
  120. </frm_item_metas>
  121. <frm_item_metas>
  122. <id>208</id>
  123. <meta_value>2014-02-03</meta_value>
  124. <field_id>88</field_id>
  125. <item_id>19</item_id>
  126. </frm_item_metas>
  127. <frm_item_metas>
  128. <id>207</id>
  129. <meta_value>Orbitrek</meta_value>
  130. <field_id>87</field_id>
  131. <item_id>19</item_id>
  132. </frm_item_metas>
  133. <frm_item_metas>
  134. <id>206</id>
  135. <meta_value>Interwały</meta_value>
  136. <field_id>86</field_id>
  137. <item_id>19</item_id>
  138. </frm_item_metas>
  139. <frm_item_metas>
  140. <id>241</id>
  141. <meta_value>732</meta_value>
  142. <field_id>100</field_id>
  143. <item_id>18</item_id>
  144. </frm_item_metas>
  145. <frm_item_metas>
  146. <id>240</id>
  147. <meta_value>132</meta_value>
  148. <field_id>97</field_id>
  149. <item_id>18</item_id>
  150. </frm_item_metas>
  151. <frm_item_metas>
  152. <id>239</id>
  153. <meta_value>10.3</meta_value>
  154. <field_id>96</field_id>
  155. <item_id>18</item_id>
  156. </frm_item_metas>
  157. <frm_item_metas>
  158. <id>237</id>
  159. <meta_value>2</meta_value>
  160. <field_id>90</field_id>
  161. <item_id>18</item_id>
  162. </frm_item_metas>
  163. <frm_item_metas>
  164. <id>238</id>
  165. <meta_value>60</meta_value>
  166. <field_id>92</field_id>
  167. <item_id>18</item_id>
  168. </frm_item_metas>
  169. <frm_item_metas>
  170. <id>236</id>
  171. <meta_value>18:30</meta_value>
  172. <field_id>99</field_id>
  173. <item_id>18</item_id>
  174. </frm_item_metas>
  175. <frm_item_metas>
  176. <id>52</id>
  177. <meta_value>60</meta_value>
  178. <field_id>92</field_id>
  179. <item_id>11</item_id>
  180. </frm_item_metas>
  181. <frm_item_metas>
  182. <id>235</id>
  183. <meta_value>2014-02-02</meta_value>
  184. <field_id>88</field_id>
  185. <item_id>18</item_id>
  186. </frm_item_metas>
  187. <frm_item_metas>
  188. <id>71</id>
  189. <meta_value>3</meta_value>
  190. <field_id>90</field_id>
  191. <item_id>13</item_id>
  192. </frm_item_metas>
  193. <frm_item_metas>
  194. <id>72</id>
  195. <meta_value>50</meta_value>
  196. <field_id>92</field_id>
  197. <item_id>13</item_id>
  198. </frm_item_metas>
  199. <frm_item_metas>
  200. <id>73</id>
  201. <meta_value>17.5</meta_value>
  202. <field_id>96</field_id>
  203. <item_id>13</item_id>
  204. </frm_item_metas>
  205. <frm_item_metas>
  206. <id>74</id>
  207. <meta_value>orbi</meta_value>
  208. <field_id>86</field_id>
  209. <item_id>14</item_id>
  210. </frm_item_metas>
  211. <frm_item_metas>
  212. <id>75</id>
  213. <meta_value>Orbitrek</meta_value>
  214. <field_id>87</field_id>
  215. <item_id>14</item_id>
  216. </frm_item_metas>
  217. <frm_item_metas>
  218. <id>76</id>
  219. <meta_value>2014-02-04</meta_value>
  220. <field_id>88</field_id>
  221. <item_id>14</item_id>
  222. </frm_item_metas>
  223. <frm_item_metas>
  224. <id>77</id>
  225. <meta_value>17:00</meta_value>
  226. <field_id>99</field_id>
  227. <item_id>14</item_id>
  228. </frm_item_metas>
  229. <frm_item_metas>
  230. <id>78</id>
  231. <meta_value>3</meta_value>
  232. <field_id>90</field_id>
  233. <item_id>14</item_id>
  234. </frm_item_metas>
  235. <frm_item_metas>
  236. <id>79</id>
  237. <meta_value>50</meta_value>
  238. <field_id>92</field_id>
  239. <item_id>14</item_id>
  240. </frm_item_metas>
  241. <frm_item_metas>
  242. <id>80</id>
  243. <meta_value>17.6</meta_value>
  244. <field_id>96</field_id>
  245. <item_id>14</item_id>
  246. </frm_item_metas>
  247. <frm_item_metas>
  248. <id>81</id>
  249. <meta_value>marszobieg</meta_value>
  250. <field_id>86</field_id>
  251. <item_id>15</item_id>
  252. </frm_item_metas>
  253. <frm_item_metas>
  254. <id>82</id>
  255. <meta_value>Marsz</meta_value>
  256. <field_id>87</field_id>
  257. <item_id>15</item_id>
  258. </frm_item_metas>
  259. <frm_item_metas>
  260. <id>83</id>
  261. <meta_value>2014-02-05</meta_value>
  262. <field_id>88</field_id>
  263. <item_id>15</item_id>
  264. </frm_item_metas>
  265. <frm_item_metas>
  266. <id>84</id>
  267. <meta_value>12:00</meta_value>
  268. <field_id>99</field_id>
  269. <item_id>15</item_id>
  270. </frm_item_metas>
  271. <frm_item_metas>
  272. <id>85</id>
  273. <meta_value>3</meta_value>
  274. <field_id>90</field_id>
  275. <item_id>15</item_id>
  276. </frm_item_metas>
  277. <frm_item_metas>
  278. <id>86</id>
  279. <meta_value>35</meta_value>
  280. <field_id>92</field_id>
  281. <item_id>15</item_id>
  282. </frm_item_metas>
  283. <frm_item_metas>
  284. <id>87</id>
  285. <meta_value>4</meta_value>
  286. <field_id>96</field_id>
  287. <item_id>15</item_id>
  288. </frm_item_metas>


I jeszcze raz - potrzebuję zsumować wartości z pola value_meta które posiadają field_id = 92 na podstawie daty która znajduje się również w polu meta_value ale posiada field_id = 88
ghost1511
Nadal nie wiem jaki przykładowy wynik chcesz otrzymać i dlaczego SUM i GROUP BY nie działają. btw takie dane ciężko się czyta.
mar1aczi
Spróbuj sobie spłaszczyć dane do jednej tabeli poprzez taka konstrukcję zapytania, jaką przytoczyłem tutaj.
Jak podajesz przykładowe dane to podaj je w formie możliwej do zaimportowania prosto do bazy/tabeli.
ghost1511
Nie wiem.... Na moje w tych danych nie ma nic nadzwyczajnego. Poczytaj trochę o złączeniach (JOINy) i wróć do tematu. Bo wygląda na to że wszystko można to łatwo osiągnąć, ale problem opisujesz w taki sposób, że ciężko cokolwiek wywnioskować.
thudy
Wybaczcie, wychodzi na to że jestem mocno raczkujący i taka struktura mnie przerasta. Nie mogę załączyć całych tabel bo cały czas mi wywala że mam za długi post, jak skrócę to dane nie mają sensu. Spróbuję jeszcze raz tak:
Tabela frm_items, pola:
id -> user_id - reszta jest nieistotna, przykładowe dane:
1 -> 1
2 -> 1
3 -> 2
4 -> 1
5 -> 2
Tabela frm_item_metas, pola:
id -> meta_value -> field_id -> item_id - (item_id to klucz obcy pochodzący z pierwszej tabeli z pola id, pod field_id = 88 występuje data, pod field_id = 92 wartość liczbowa do sumowania)
1 -> 60 -> 92 -> 1
2 -> 2014-02-14 -> 88 -> 1
3 -> 40 -> 92 -> 2
4 -> 2014-01-04 -> 88 -> 2
5 -> 20 -> 92 -> 3
6 -> 2014-02-05 -> 88 -> 3
7 -> 60 -> 92 -> 4
8 -> 2014-01-01 -> 88 -> 4
9 -> 10 -> 92 -> 5
10 -> 2014-02-02 -> 92 ->5

I teraz robię tak jak wspomniałem wcześniej:
  1. SELECT SUM(meta_value)AS suma
  2. FROM `frm_item_metas`
  3. JOIN `frm_items`
  4. ON frm_items.id = frm_item_metas.item_id
  5. WHERE `user_id` = 1
  6. AND `field_id` =92

Otrzymuję sumę wszystkich wartości z pola meta_value, w rekordzie gdzie field_id=92 i wartość to 160, ale ja chciałbym dodatkowo wprowadzić jeszcze wyszukiwanie po dacie, np. suma rekordów w poprzednim miesiącu (powinno wyjść 100) lub aktualnym czyli luty (60).
Mam nadzieję że teraz się dobrze wyraziłem - dzięki za cierpliwość
mmmmmmm
  1. SELECT miesiac, sum(cast(meta_value AS decimal))
  2. FROM `frm_item_metas` f
  3. JOIN (
  4. SELECT month(meta_value) miesiac, item_id
  5. FROM frm_item_metas
  6. WHERE field_id =88
  7. /* AND meta_value BETWEEN '2014-02-01' AND '2014-02-28' */
  8. )sub ON f.item_id = sub.item_id
  9. WHERE field_id =92
  10. GROUP BY 1
thudy
Cytat(mmmmmmm @ 19.02.2014, 21:11:14 ) *
  1. SELECT miesiac, sum(cast(meta_value AS decimal))
  2. FROM `frm_item_metas` f
  3. JOIN (
  4. SELECT month(meta_value) miesiac, item_id
  5. FROM frm_item_metas
  6. WHERE field_id =88
  7. /* AND meta_value BETWEEN '2014-02-01' AND '2014-02-28' */
  8. )sub ON f.item_id = sub.item_id
  9. WHERE field_id =92
  10. GROUP BY 1

Wyższa szkoła jazdy ohno-smiley.gif wszystko pięknie, ładnie, tylko chyba muszę jeszcze jednego połączenia dokonać z tablicą frm_items gdzie mam user_id ?
mmmmmmm
  1. SELECT `miesiac`, sum(cast(`meta_value` AS decimal))
  2. FROM `frm_item_metas` f
  3. JOIN (
  4. SELECT month(`meta_value`) miesiac, `item_id`
  5. FROM `frm_item_metas`
  6. WHERE `field_id`=88
  7. /* AND `meta_value` BETWEEN '2014-02-01' AND '2014-02-28' */
  8. )sub ON f.`item_id` = sub.`item_id`
  9. JOIN `frm_items` fi
  10. ON fi.`id` = f.`item_id`
  11. WHERE `field_id`=92 AND fi.`user_id`=1
  12. GROUP BY 1
thudy
Wielkie dzięki - wszystko jest OK yahoo.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.