Как стать автором
Обновить
2
0

Пользователь

Отправить сообщение

Статья в вики, по крайней мере, четко определяет формальный алгоритм работы соединений.


Не спорю, хороших статей на эту тему много

Имхо, стоило бы дать ссылки на эти хорошие статьи, дополнив ими перевод.

Очень примитивное описание соединений, которое только провоцирует непонимание их работы.
Статья в Википедии https://ru.wikipedia.org/wiki/Join_(SQL) гораздо лучше.

Ну, во-первых, о том, что про понятие "комфортная жизнь" пора уже начинать забывать, я написал выше.


Во-вторых, есть шанс что глобального армагедонна все же не будет.

Сравните две альтернативы "жить не сладко" и "выживать" и далее принимайте решение.


Свалить куда?

Боюсь накаркать, но, похоже, что решение надо принимать их соображений "подальше от зоны потенциального обмена ядерными ударами". Возможно Австралия/Новая Зеландия.

предложить вакансии российским разработчикам и продавать их услуги на запад

Продажа услуг на запад? Вы на потенциальных врагов РФ работать собрались? А пятнашечку не хотите?


Лучшее, что может сделать айтишник сегодня — свалить. Иначе шарашка в недалекой перспективе.

Ну покажите, хоть разочек, хоть примерчик, хоть в какой СУБД

Предполагаю, что, в каких то древних СУБД, такое поведение могло и быть. С той поры и дуют на воду :)

Неправильная мантра :)


Надо избегать выражений по индексируемым полям.
Вместо
ABS(column) = 100
Надо писать
column in (-100,100)


Вместо
YEAR(column) =2008
надо
column between '20080101' AND '20081231'


и т.д. и т.п.

Вы, похоже, путаете ситуацию с абсолютно идентичным в плане результата запросом по фильтру:


WHERE 2 = column - 2

Вот тут будет полный скан, причем независимо от того, где стоит выражение, справа или слева.

Я то проверил (MS SQL 2008) и убедился еще раз в том, что и так знал. Планы идентичны.
Теперь ваши пруфы в студию.

Пример СУБД в студию, в которой план выполнения запроса с
WHERE 2+2 = column
отличается от
WHERE column = 2+2

Почему не упомянут 100% надежный способ борьбы с парсингом? Убрать цены нахрен с сайта! Хотите что-нибудь купить — пишите заверенное нотариусом письмо и вам вышлют прайс в экселе. Хотя, пардон, какой эксель? Его же легко обработать. Нет, только скан распечатки внутри PDF, только хардкор!


Это и есть настоящий Ё-commerce!

Это какой же должен быть примитивный оптимизатор, что бы это было правдой?

Это еще одно БОЛЬШОЕ заблуждение думать, что движок СУБД будет выполнять запрос так как вы думаете. :)
Для того и существует внутри его оптимизатор запросов. Который, скорее всего, сделает все строго наоборот! То есть сначала отфильтрует записи (особенно если есть соответствующий индекс), а затем будет выполнять объединение.


Пытаться оптимизировать таким способом запросы бесполезно.

И автовыкуп, ради чего бы он не делался, надо пресекать

Сначала надо дать легальный инструмент для продавца для отзыва товара за вменяемый процент, а потом уже начинать шашкой махать.

Нельзя просто так взять и отозвать товар со складов. Возвращать получается сопоставимо с его себестоимостью

А это как то объясняется маркетплейсом? То есть отправить товар тысячам розничных покупателей маркетплейсу не трудно и не дорого. Отправить назад одному продавцу ну очень сложно… Так сложно, что очень дорого. Что-то не понятно.

Куда тут применить "сначала группировать по Column_id, а потом подтягивать текстовые значения джойном"?

Ну как бы вы в своих примерах уже совсем, совсем далеко уехали от исходной формулировки abratash. Который призывал при наличии возможности группировки одновременно как по имени так и по коду, отдать предпочтение группировке по коду. В вашем примере


SELECT Column_name, MAX(Column_id) greatest_id
FROM table
GROUP BY Column_name

никаких взаимозаменяемых группировок нет и поэтому и применить нечего.


Вот пример соответствующий формулировке abratash.


SELECT
    Column_id,
    Column_name,
    SUM(amount)
FROM 
     table
GROUP BY
    Column_id,
    Column_name

Когда есть однозначное соответствие Column_id, Column_name можно написать:


SELECT
    T.Column_id,
    N.Column_name,
    T.amount
FROM
(
   SELECT
       Column_id,
       SUM(amount) amount
   FROM 
        table
   GROUP BY
       Column_id
 ) T INNER JOIN (SELECT DISTINCT Column_id,Column_name FROM table) N
     ON T.Column_id = N.Column_id

Я, например, не уверен что это будет работать быстрее во всех случаях. А скорее всего для обычных имен даже и медленнее.


Если нет однозначного соответствия Column_id и Column_name (название не нормализовано и может содержать орфографические и прочие ошибки), и какое конкретно название выберется не принципиально, то можно написать в качестве подзапроса N:


 (SELECT Column_id, MAX(Column_name) AS Column_name FROM table GROUP BY Column_id) N

Если важно взять последнее название, то тогда в ход идет ROW_NUMBER() :


(
   SELECT Column_id, Column_name 
   FROM 
   (
      SELECT Column_id, Column_name,
          ROW_NUMBER() OVER (PARTITION BY Column_id ORDER BY Date DESC) n
      FROM table
   ) WHERE n=1
) N

Сразу говорю, я с вами полностью согласен, что, в этом случае, это плохо спроектированная БД. Но, в реальной жизни, с какими только данными не приходится работать, увы.

описанного однозначного соответствия нет. Но тогда совет из Вашего комментария неприменим.

Применим и еще как, но с использованием подзапроса с ROW_NUMBER() AS n и дальнейшего фильтра по n=1

Ну вопрос же ваш звучал так:


Как выразить это через WHERE?

а не "зачем" :). А так то я не спорю с нужностью дополнительных условий в JOIN.

смысл в таком использовании может присутствовать.

Скажем так… В правильно спроектированных БД такое использование — экзотика. Но, т.к. в жизни правильно спроектированные БД сами являются экзотикой :), то этот прием применяется довольно часто.
Вот еще пример из жизни, я его называю "switch JOIN":


SELECT 
    Main.*,
    COALESCE(T3.id,T2.id,T1.id) refT
FROM Main
    LEFT OUTER JOIN T T1
         ON Main.Cod = T1.Cod AND T1.Flag=1
    LEFT OUTER JOIN T T2
         ON T1.id IS NULL -- второй раз подключаем справочник, если по полю Cod соответствия не найдено. 
            AND Main.Num BETWEEN T2.MinNum AND T2.MaxNum AND T2.Flag=2
    LEFT OUTER JOIN T T3
         ON T2.id IS NULL  
            AND Main.Text Like T3.Pattern AND T3.Flag=3

Подключаем записи из справочника в соответствии с приоритетом. Если найдено совпадение по полю Cod, то берутся они. Если ни одной такой записи не найдено, то пробуем найти соответствие по полю Num, и, наконец, если ничего не нашли, то по полю Text. Я вот так сходу и не соображу как это красиво переписать без использования констант в предикатах.


нет, непонятно было не как работает, а зачем

Надеюсь разъяснил :)

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Витебск, Витебская обл., Беларусь
Зарегистрирован
Активность