'SELECT *' из внутренних объединенных таблиц - PullRequest
2 голосов
/ 18 мая 2009

Как выбрать все поля двух соединенных таблиц, не конфликтуя с общим полем?

Предположим, у меня есть две таблицы, Products и Services. Я хотел бы сделать запрос, подобный этому:

SELECT Products.*, Services.* 
FROM Products 
INNER JOIN Services ON Products.IdService = Services.IdService

Проблема с этим запросом состоит в том, что IdService появится дважды и приведет к куче проблем.

Альтернатива, которую я нашел до сих пор, состоит в том, чтобы отличать каждое поле от Products, кроме IdService. Но таким образом мне придется обновлять запрос каждый раз, когда я добавляю новое поле в Products.

Есть ли лучший способ сделать это?

Ответы [ 8 ]

13 голосов
/ 18 мая 2009

Вы никогда не должны иметь SELECT * в рабочем коде (ну, почти никогда, но времена, когда это оправдано, легко подсчитать).

12 голосов
/ 18 мая 2009

Каковы наиболее распространенные анти-паттерны SQL?

Вы нажали анти-шаблон # 1.

Лучший способ - предоставить список полей. Один из способов получить быстрый список полей -

sp_help tablename

И если вы хотите создать представление из этого запроса - использование select * доставит вам больше хлопот. SQL Server захватывает список столбцов во время создания представления. Если вы редактируете базовые таблицы и не воссоздаете представление - вы подписываетесь на неприятности (у меня был производственный пожар такого рода - хотя представление было против таблиц в другой базе данных).

3 голосов
/ 18 мая 2009

Насколько я знаю, вам придется избегать SELECT *, но это не проблема.

SELECT * обычно рассматривается как проблема, ожидающая того, что произойдет по той причине, которую вы указываете как преимущество! Обычно дополнительные столбцы результатов, появляющиеся для запросов при изменении базы данных, вызывают проблемы.

1 голос
/ 18 мая 2009

Не использовать *. Используйте что-то вроде этого:

SELECT P.field1 AS 'Field from P'
     , P.field2
     , S.field1 AS 'Field from S'
     , S.field4 
  FROM Products P
       INNER JOIN 
       Services S
       ON P.IdService = S.IdService
1 голос
/ 18 мая 2009

Как уже говорили другие, Select * - это плохие новости, особенно если в таблицы, в которые вы запрашиваете, добавляются другие поля. Вы должны выбрать нужные поля из таблиц и использовать псевдоним для полей с одинаковыми именами или просто использовать table.columnName.

1 голос
/ 18 мая 2009

Ваш диалект SQL поддерживает COMPOSE? КОМПОЗИЦИЯ избавляется от дополнительной копии столбца, который используется в эквиджоине, как в вашем примере.

0 голосов
/ 18 мая 2009

Лучший способ - указать точные поля, которые вы хотите получить из запроса. Вы не должны использовать * в любом случае.

Удобно использовать * для получения всех полей, но это не дает надежного кода. Любое изменение в таблице изменит результат, возвращаемый запросом, что не всегда желательно.

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

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

0 голосов
/ 18 мая 2009

Это было бы правильно, перечислите нужные поля (в SQL Server вы можете перетаскивать их из браузера объектов, чтобы вам не приходилось вводить их все). Кстати, если есть поля, в которых ваш конкретный запрос не нужен, не перечисляйте их. Это создает дополнительную работу для сервера и использует дополнительные сетевые ресурсы и может быть одной из причин плохой производительности, когда это выполняется в вашей системе, а такие расточительные запросы выполняются тысячи раз в день.

В связи с тем, что это проблема технического обслуживания, вам нужно добавить поля только в том случае, если они затронут ту часть приложения, которая использует ваш запрос. Если вы не знаете, как повлияет новое поле или где его нужно добавить, добавлять поле не следует. Также неожиданно добавление новых файлов с помощью select * может также вызвать проблемы с обслуживанием. Создание проблем производительности, чтобы избежать обслуживания (обслуживание, которое вам, возможно, даже не понадобится, поскольку изменения столбцов должны быть редкими (если вам не нужно смотреть на ваш дизайн)), довольно недальновидно.

...