Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Jak kilka SELECT połączyć w 1 zapytanie sql
zielq701
post
Post #1





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 8.07.2013

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/tongue.gif) .
Go to the top of the page
+Quote Post
phpion
post
Post #2





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #3





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


  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 */

Go to the top of the page
+Quote Post
phpion
post
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




@mmmmmmm:
Do tego potrzeba jeszcze tego, co opisałem w punkcie nr 2.
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #5





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


Nie trzeba. Można to na kliencie zrobić.
Go to the top of the page
+Quote Post
zielq701
post
Post #6





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 8.07.2013

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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. ?>


Ten post edytował zielq701 22.05.2015, 21:48:02
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 28.09.2025 - 22:13