Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jak kilka SELECT połączyć w 1 zapytanie sql
Forum PHP.pl > Forum > Bazy danych > MySQL
zielq701
Witam wszystkich,
piszę proste api do planera dnia. Czy da się zastąpić 3 SELECTY jednym aby otrzymać następującą odpowiedź:

  1. (
  2. [2015-05-22] => Array
  3. (
  4. [timed] => Array
  5. (
  6. [0] => Array
  7. (
  8. [id] => 16
  9. [user_id] => 1
  10. [task] => Testowe zadanie specjalne
  11. [note] => Testowo testować testowane zadania. Test testowy testowany testowo wielokrotnie.
  12. [priority_id] => 1
  13. [date] => 2015-05-22
  14. [time] => 00:00:00
  15. [done] => 0
  16. [timestamp] => 2015-05-22 09:59:34
  17. )
  18.  
  19. )
  20.  
  21. [other] => Array
  22. (
  23. [0] => Array
  24. (
  25. [id] => 14
  26. [user_id] => 1
  27. [task] => Testowe zadanie specjalne
  28. [note] => Testowo testować testowane zadania. Test testowy testowany testowo wielokrotnie.
  29. [priority_id] => 1
  30. [date] => 2015-05-22
  31. [time] =>
  32. [done] => 0
  33. [timestamp] => 2015-05-22 09:59:20
  34. )
  35.  
  36. )
  37.  
  38. [done] => Array
  39. (
  40. )
  41.  
  42. )
  43.  
  44. [2015-05-23] => Array
  45. (
  46. [timed] => Array
  47. (
  48. [0] => Array
  49. (
  50. [id] => 15
  51. [user_id] => 1
  52. [task] => Testowe zadanie specjalne
  53. [note] => Testowo testować testowane zadania. Test testowy testowany testowo wielokrotnie.
  54. [priority_id] => 1
  55. [date] => 2015-05-23
  56. [time] => 00:00:00
  57. [done] => 0
  58. [timestamp] => 2015-05-22 09:59:23
  59. )
  60.  
  61. )
  62.  
  63. [other] => Array
  64. (
  65. )
  66.  
  67. [done] => Array
  68. (
  69. )
  70.  
  71. )
  72.  
  73. )


Bardzo mi zależy na takiej strukturze tabeli. Tak wygląda teraz część mojego kodu w php:

  1. class DataProvider {
  2. private $db;
  3.  
  4. public function __construct($db)
  5. {
  6. $this->db = $db;
  7. }
  8.  
  9. public function getRequestData()
  10. {
  11. return json_decode(file_get_contents('php://input'), true);
  12. }
  13.  
  14. public function getTasks($userId, $date)
  15. {
  16. //pobiera zadania ktore maja okreslona godzine i NIE zostaly wykonane
  17. $sql = "SELECT ds_tasks.*
  18. FROM ds_tasks LEFT JOIN ds_priorities
  19. ON ds_tasks.priority_id=ds_priorities.id
  20. WHERE user_id = :uid AND `date` = :date AND done = 0 AND`time` IS NOT NULL";
  21.  
  22. $timed = $this->db->fetchAll($sql, array( 'uid' => (int) $userId, 'date' => $date));
  23.  
  24. //pobiera zadania ktore NIE maja okreslonej godziny i NIE zostaly wykonane
  25. $sql = "SELECT ds_tasks.*
  26. FROM ds_tasks LEFT JOIN ds_priorities
  27. ON ds_tasks.priority_id=ds_priorities.id
  28. WHERE user_id = :uid AND `date` = :date AND done = 0 AND `time` IS NULL";
  29.  
  30. $other = $this->db->fetchAll($sql, array( 'uid' => (int) $userId, 'date' => $date));
  31.  
  32. //pobiera zadania ktore sa wykonane
  33. $sql = "SELECT ds_tasks.*
  34. FROM ds_tasks LEFT JOIN ds_priorities
  35. ON ds_tasks.priority_id=ds_priorities.id
  36. WHERE user_id = :uid AND `date` = :date AND done = 1 AND `time` IS NULL";
  37.  
  38. $done = $this->db->fetchAll($sql, array( 'uid' => (int) $userId, 'date' => $date));
  39.  
  40. //tworzy tabele z zadaniami
  41. $tasks = array (
  42. 'timed' => $timed,
  43. 'other' => $other,
  44. 'done' => $done
  45. );
  46. return $tasks;
  47. }
  48.  
  49. public function getTimeIntervalTasks($userId, $date, $endDate)
  50. {
  51. $tasks = array();
  52.  
  53. while (strtotime($date) <= strtotime($endDate)) {
  54.  
  55. $tasks[$date] = $this->getTasks($userId, $date);
  56.  
  57. $date = date("Y-m-d", strtotime("+1 day", strtotime($date)));
  58. }
  59.  
  60. return $tasks;
  61. }
  62. }


Z góry dzięki za jakąkolwiek pomoc tongue.gif.
phpion
UNION
Na dobrą sprawę te 3 zapytania różnią się tylko częścią warunków więc możesz wyodrębnić te różnice w warunkach i wstawić je między OR'y. Będziesz jeszcze musiał się dowiedzieć z której serii warunków otrzymałeś rekord - tutaj skorzystaj z CASE w liście pobieranych kolumn.

Czyli:
1. WHERE ... AND ((jakieś warunki) OR (inne warunki) OR (i jeszcze inne))
2. SELECT ... (CASE WHEN (jakieś warunki) THEN 'timed' WHEN ... END) AS rodzaj
mmmmmmm
  1. $sql = "SELECT ds_tasks.*
  2. FROM ds_tasks LEFT JOIN ds_priorities
  3. ON ds_tasks.priority_id=ds_priorities.id
  4. WHERE user_id = :uid AND `date` = :date AND (done = 0 OR `time` IS NULL)";
  5. /* zakladam, ze done moze miec TYLKO wartosci 0 lub 1 */

phpion
@mmmmmmm:
Do tego potrzeba jeszcze tego, co opisałem w punkcie nr 2.
mmmmmmm
Nie trzeba. Można to na kliencie zrobić.
zielq701
Cytat(phpion @ 22.05.2015, 13:48:54 ) *
UNION
Na dobrą sprawę te 3 zapytania różnią się tylko częścią warunków więc możesz wyodrębnić te różnice w warunkach i wstawić je między OR'y. Będziesz jeszcze musiał się dowiedzieć z której serii warunków otrzymałeś rekord - tutaj skorzystaj z CASE w liście pobieranych kolumn.

Czyli:
1. WHERE ... AND ((jakieś warunki) OR (inne warunki) OR (i jeszcze inne))
2. SELECT ... (CASE WHEN (jakieś warunki) THEN 'timed' WHEN ... END) AS rodzaj


Póki co mam takie coś: http://pastebin.com/5rES0JKv

Nie usne jak nie będę wiedzieć jak ma wyglądać takie zapytanie. Pomóżcie biggrin.gif

-------------------------------------------------- edit
Ciągle takie nieeleganckie rozwiązanie... w komentarzu na koncu opisalem problem.

  1. <?php
  2. namespace Scheduler\Provider;
  3.  
  4. class DataProvider {
  5. private $db;
  6.  
  7. public function __construct($db)
  8. {
  9. $this->db = $db;
  10. }
  11.  
  12. public function getTasks($userId, $date)
  13. {
  14. // pobieranie zadan okreslonych godzinowe i niezrobionych
  15. $sql = "SELECT ds_tasks.`id`
  16. , ds_tasks.`task`
  17. , ds_tasks.`note`
  18. , ds_priorities.`priority`
  19. , ds_priorities.`css_class`
  20. , ds_tasks.`date`
  21. , ds_tasks.`time`
  22. , ds_tasks.`done`
  23. FROM ds_tasks LEFT JOIN ds_priorities
  24. ON ds_tasks.`priority_id` = ds_priorities.`id`
  25. WHERE user_id = ? AND `date` = ? AND `done` = 0 AND `time` IS NOT NULL
  26. ORDER BY `time`";
  27.  
  28. $timed = $this->db->fetchAll($sql, array((int) $userId, $date));
  29.  
  30. // pobieranie zadan nie okreslonych godzinowo i niezrobionych
  31. $sql = "SELECT ds_tasks.`id`
  32. , ds_tasks.`task`
  33. , ds_tasks.`note`
  34. , ds_priorities.`priority`
  35. , ds_priorities.`css_class`
  36. , ds_tasks.`date`
  37. , ds_tasks.`time`
  38. , ds_tasks.`done`
  39. FROM ds_tasks LEFT JOIN ds_priorities
  40. ON ds_tasks.`priority_id` = ds_priorities.`id`
  41. WHERE user_id = ? AND `date` = ? AND `done` = 0 AND `time` IS NULL
  42. ORDER BY `priority` DESC";
  43.  
  44. $other = $this->db->fetchAll($sql, array((int) $userId, $date));
  45.  
  46. // pobieranie wszystkich zadan zrobionych
  47. $sql = "SELECT ds_tasks.`id`
  48. , ds_tasks.`task`
  49. , ds_tasks.`note`
  50. , ds_priorities.`priority`
  51. , ds_priorities.`css_class`
  52. , ds_tasks.`date`
  53. , ds_tasks.`time`
  54. , ds_tasks.`done`
  55. FROM ds_tasks LEFT JOIN ds_priorities
  56. ON ds_tasks.`priority_id` = ds_priorities.`id`
  57. WHERE user_id = ? AND `date` = ? AND `done` = 1
  58. ORDER BY `timestamp` DESC";
  59.  
  60.  
  61. $done = $this->db->fetchAll($sql, array((int) $userId, $date));
  62.  
  63. // laczenie wszystkich zadan w jedna tablice
  64. $tasks = array (
  65. 'timed' => $timed,
  66. 'other' => $other,
  67. 'done' => $done
  68. );
  69.  
  70. return $tasks;
  71. }
  72.  
  73.  
  74. // Wywoluje, w celu pobrania zadan z dnia, funkcje getTasks()
  75. //
  76. // jezeli podam zakres obejmujacy 14 dni wykonuje
  77. // 42 zapytania do bazy, poniewaz getTasks() ma 3 zapytania.
  78. //
  79. // czy da się jakoś uszczuplic ilosc zapytan do bazy
  80. // aby nie zmienic struktury zwracanej tablicy?
  81. // klucze tablicy powinny pozostac takie jakie sa
  82. //
  83. // struktura tablicy:
  84. // Array
  85. // (
  86. // [2015-05-23] => Array
  87. // (
  88. // [timed] => Array (zadania okreslone w czasie...)
  89. // [other] => Array (inne zadania...)
  90. // [done] => Array (zadania wykonane....)
  91. // )
  92. // [2015-05-24] => Array
  93. // (
  94. // [timed] => Array (-//-)
  95. // [other] => Array (-//-)
  96. // [done] => Array (-//-)
  97. // )
  98. // .
  99. // .
  100. // .
  101. // .itd.
  102. // )
  103. public function getTimeIntervalTasks($userId, $date, $endDate)
  104. {
  105. $tasks = array();
  106.  
  107. while (strtotime($date) <= strtotime($endDate)) {
  108.  
  109. $tasks[$date] = $this->getTasks($userId, $date);
  110.  
  111. $date = date("Y-m-d", strtotime("+1 day", strtotime($date)));
  112. }
  113. return $tasks;
  114. }
  115. }
  116. ?>
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.