"PHP" / Говнокод #10061 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
$sql = "SELECT (SELECT Name FROM dbo.RoutesTypes WHERE RowID = Type) AS Name --Название маршрута
      ,(SELECT Name FROM dbo.Destinations WHERE Name = '$Src') AS DestA --Пункт отправления
      ,(SELECT Name FROM dbo.Destinations WHERE Name = '$Dst') AS DestB --Пункт назначения
      --,(SELECT COUNT([RowID]) FROM [RoutePartInstances] WHERE [RoutePartType] = RoutesTypes.RowID AND [Occuped] = 0) AS FreePlaces --Количество свободных мест на выбранную часть маршрута
      ,(SELECT SUM(Cost) From RoutesParts WHERE Ordern >= RoutesTypes.OrderA AND Ordern <= RoutesTypes.OrderB AND InstanceID = Type) AS TicketCost --Стоимость билета на выбранную часть маршрута
      ,(SELECT SUM(TimeInWay) From RoutesParts WHERE Ordern >= RoutesTypes.OrderA AND Ordern <= RoutesTypes.OrderB AND InstanceID = Type) AS TimeInWay --Время в пути на выбранной части маршрута
		--Расчёт времени отправления
      ,(SELECT DATEADD(Minute, 
            (SELECT 
				CASE
					WHEN RoutesTypes.OrderA > 1 THEN (SELECT SUM(TimeInWay) From RoutesParts WHERE Ordern < RoutesTypes.OrderA AND InstanceID = Type)+10*(SELECT COUNT(RowID) From RoutesParts WHERE Ordern < RoutesTypes.OrderA AND InstanceID = Type)
					ELSE 0
				END),[DateStart])) AS DepartureTime
		--Расчёт времени прибытия
      ,(SELECT DATEADD(Minute,
		   (SELECT SUM(TimeInWay) From RoutesParts WHERE Ordern >= RoutesTypes.OrderA AND Ordern <= RoutesTypes.OrderB AND InstanceID = Type)+10*(SELECT COUNT(RowID) From RoutesParts WHERE Ordern > RoutesTypes.OrderA AND Ordern <= RoutesTypes.OrderB AND InstanceID = Type), 
			   (SELECT DATEADD(Minute, 
				   (SELECT 
						CASE
							WHEN RoutesTypes.OrderA > 1 THEN (SELECT SUM(TimeInWay) From RoutesParts WHERE Ordern < RoutesTypes.OrderA AND InstanceID = Type)+10*(SELECT COUNT(RowID) From RoutesParts WHERE Ordern < RoutesTypes.OrderA  AND InstanceID = Type)
					ELSE 0
				END),[DateStart])))) AS ArrivalTime
	
	--,RoutesTypes.OrderA --Порядок выбранной точки отправления в маршруте. Это нам понадобится при покупке билета
    --,RoutesTypes.OrderB --Порядок выбранной точки назначания в маршруте. Это нам понадобится при покупке билета
    --,RoutesTable.[RowID] AS RouteID --Идентификатор рейса из таблицы расписаний. Это нам понадобится при покупке билета
    --,RoutesTable.[Type] AS RouteTypeID --Идентификатор типа маршрута из таблицы типов маршрутов. Это нам понадобится при покупке билета

  FROM [RoutesTable] AS RoutesTable
  INNER JOIN	(SELECT RoutesParts_A.[InstanceID],RoutesParts_A.[TimeA],RoutesParts_B.TimeB,RoutesParts_A.RowID,RoutesParts_  A.Ordern AS OrderA,RoutesParts_B.Ordern AS OrderB
				FROM [RoutesParts] AS RoutesParts_A
				INNER JOIN (SELECT [InstanceID],[TimeB],[Ordern] FROM [RoutesParts] WHERE [DestBID] = (SELECT RowID FROM Destinations WHERE Name = '$Dst')) AS RoutesParts_B ON RoutesParts_B.InstanceID = RoutesParts_A.InstanceID
				WHERE [DestAID] = (SELECT RowID FROM Destinations WHERE Name = '$Src'))AS RoutesTypes ON RoutesTable.Type = RoutesTypes.InstanceID";

Встретил на форуме phpforum.ru. Человек интересовался почему не работает запрос :)

Запостил: vagrand vagrand, (Updated )

Комментарии (15) RSS

  • Как-то тут много PHP. Даже слишком.

    P.S. Подселекты - злое зло.
    Ответить
      • Сорри, не читаю старые треды.
        Не проверял, возможно, сильно specific для базы. На какой-то из DB2/AS400 подзапросы отрабатывали сильно медленнее. Кроме того, как я уже, кажется, писал, можно применять подзапрос в секции where (иногда без него не обойтись в случае update/delete statement). В секции SELECT за подзапрос нужно насиловать кочергой, в секции FROM тоже не должно допускать подобного, кроме случаев, когда база не поддерживает более вкусные ништяки типа WITH, или если другого способа собрать таблицу не существует (например, выборка из VIEW, к которому потребно условие, а портить сам вью не хочется).
        В данном коде мы и наблюдаем бесполезные и несвязанные выборки в секции SELECT (особого безумия доставляет SELECT param FROM table WHERE param = var), как и в секции FROM, где можно развернуть без запроса внутри.

        Резюмируя:
        delete from mytable where id in (select id from othertable group by id having count(*)>1) - годный и валидный запрос, остальное всё от лукавого.

        P.S. Да, не стоит забывать, как правильно в том треде отметили, иногда подзапрос может выполняться для каждой строки родительского запроса, чего допускать совсем-совсем нельзя.

        Надеюсь, на этом моё изложение видения вопроса всех удовлетворит.
        Ответить
        • >В секции SELECT за подзапрос нужно насиловать кочергой
          +=1
          > в секции FROM тоже не должно допускать подобного, кроме случаев, когда база не поддерживает более вкусные ништяки
          +=1

          >Не проверял, возможно, сильно specific для базы. На какой-то из DB2/AS400 подзапросы отрабатывали сильно медленнее.

          На самом деле больше зависит от типа данных.
          Но если рассматривать сферический случай в абсолютном вакууме когда все хорошо написанно при прочих равных подзапрос NOT exists должен быть быстрее.
          И вот почему. Not exists - ищет до первого совпадения и потом просто отсеивает запись из выборки.
          Left outer join, наоборот выбирает все совпадения и включая те что отсутствуют во второй таблице, и только потом убирает те записи которые нам не нужны. А поскольку в типичных таблицах inner связок зачастую гораздо больше, чем not existов, то работает оно дольше.

          То есть Left outer join теоретически делает больше работы джойня всё и потом отсеивая ненужное.
          Ответить
        • А у VIEW есть какие-либо противопоказания или побочные эффекты?
          Ответить
  • Хотелось бы взглянуть на PHP код автора...
    А SQL-скил говную.
    Ответить
  • я бы удивился, если бы эта подтирка работала бы.

    неистребимо стремление джуников "стартовать на второй передаче" - пихать в одно предложение (запрос) всю функциональность.
    Ответить
  • Если у вас всех запросы состоят из селекта и where, то это не значит, что остальным людям не доверяют серьёзные проекты. Хотя, конечно, этот запрос - говно.
    Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8