Чому символи підстановки в заявах GROUP BY не працюють?


29

Я намагаюся змусити наступний оператор SQL працювати, але я отримую синтаксичну помилку:

SELECT A.*, COUNT(B.foo)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.PKey = B.FKey
GROUP BY A.*

Тут A - це широка таблиця з 40 стовпцями, і я хотів би уникати перерахування назви кожного стовпця в пункті GROUP BY, якщо це можливо. У мене є багато таких таблиць, над якими мені потрібно виконати подібний запит, тому мені доведеться написати процедуру, що зберігається. Який найкращий спосіб підійти до цього?

Я використовую MS SQL Server 2008.

Відповіді:


32

GROUP BY A.* заборонено в SQL.

Ви можете обійти це за допомогою підзапиту, за яким ви групуєтесь, а потім приєднайтесь:

SELECT A.*, COALESCE(B.cnt, 0) AS Count_B_Foo
FROM TABLE1 AS A
  LEFT JOIN 
      ( SELECT FKey, COUNT(foo) AS cnt
        FROM TABLE2 
        GROUP BY FKey
      ) AS B 
    ON A.PKey = B.FKey ;

У стандарті SQL-2003 є особливість допускати в SELECTсписку стовпці, яких немає в GROUP BYсписку, доки вони функціонально залежать від них. Якби ця функція була реалізована в SQL-сервері, ваш запит міг бути записаний так:

SELECT A.*, COUNT(B.foo)
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.PKey = B.FKey
GROUP BY A.pk                          --- the Primary Key of table A

На жаль, ця функція ще не реалізована, навіть у версії SQL-Server 2012 - і не в будь-якій іншій СУБД, наскільки я знаю. За винятком MySQL, який має його, але неадекватно (неадекватно як: вищезазначений запит буде працювати, але двигун не буде перевіряти функціональну залежність, а інші неправильно написані запити не показуватимуть неправильних, напів випадкових результатів).

Як @Mark Byers повідомив нам у коментарі, PostgreSQL 9.1 додав нову функцію, розроблену для цієї мети. Він більш обмежений, ніж реалізація MySQL.


Чи можете ви згадати пару RDBMS, які реалізують цю частину стандарту, як написано? Я знаю, наприклад, що MySQL дозволить вам (з урахуванням належних налаштувань) включити GROUP BYдо SELECTсписку елементи, що не входять до цього пункту , але він не визначає, з якого рядка це значення буде надходити (так, якщо стовпець або вираз isn ' функціонально не залежать від виразу групування, тоді він може походити з будь-якого рядка в групі).
Адам Робінсон

@Adam: Ні, я не знаю жодної RDBMS, яка б її реалізувала. MySQL має його, але недостатньо, як говорить ваш коментар.
ypercubeᵀᴹ

Готча. Я насправді запитував, чи є, оскільки у мене є досвід роботи з набагато меншою кількістю RDBMS, ніж я б міг уявити, що більшість людей, які відповідають на запитання на цьому сайті, мали б;) Але це було моє підозру.
Адам Робінсон

3
", а не в будь-якій іншій СУБД, наскільки я знаю." PostgreSQL 9.1 додав нову функцію, розроблену для цієї мети. Він більш обмежений, ніж реалізація MySQL.
Марк Байєрс

@MarkByers: thnx, я цього не знав.
ypercubeᵀᴹ

24

Окрім способу вирішення @ ypercube, "набір тексту" ніколи не є приводом для використання SELECT *. Я писав про це тут , і навіть при вирішенні питання я думаю, що у вашому SELECTсписку все-таки повинні бути назви стовпців - навіть якщо існує така кількість, як 40.

Якщо коротко розповісти, ви можете уникнути набору цих великих списків, натиснувши та перетягнувши вузол стовпців для об’єкта в Провіднику об’єктів у вікно запиту. Знімок екрана показує вид, але те саме можна зробити і для столу.

введіть тут опис зображення

Але якщо ви хочете прочитати про всі причини, чому ви повинні піддатися цьому величезному рівню зусиль, щоб перетягнути предмет на кілька сантиметрів, будь ласка, прочитайте мій пост . :-)


У PostgreSQL (за допомогою EMS SQL Manager) я роблю це, визначаючи подання як, SELECT *а потім копіюю список полів із визначення перегляду.
dezso

Я, безумовно, згоден, що SELECT *не слід використовувати. Мені цікаво GROUP BYсправа. @Aaron, чи є проблеми з ефективністю, коли 40 списків у списку групи за списком?
ypercubeᵀᴹ

1
@ypercube - Наскільки я бачив, якщо ваша група за A.PK, A.some, A.other, A.columnsцим не турбує насправді порівняння, some, other, columnsце просто вимагає синтаксис.
Мартін Сміт

1
@datagod Вибачте, ні, будь-які прогалини могли бути пояснені лише командою розробників SSMS. :-)
Аарон Бертран

1
@Pacerier Вибачте, я зовсім не погоджуюся , але, можливо, ви могли б детальніше розглянути .
Аарон Бертран
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.