Привязка имени MySQL?

SELECT Score, (SELECT COUNT(*) FROM (SELECT DISTINCT Score FROM Scores WHERE Score >= s.Score) AS tmp) AS Rank
FROM Scores s
ORDER BY Score DESC

Может кто-нибудь сказать мне, почему столбец s.score неизвестен внутреннему подзапросу?

1 ответ

Решение

Тот correlated subquery ("tmp") слишком глубоко вложен, в действительности детали "tmp" не известны внешнему запросу:

SELECT
      Score
    , (
            SELECT
                  COUNT(*)
            FROM ( ------------------------------
                  SELECT DISTINCT
                        Score
                  FROM Scores
                  WHERE Score >= s.Score
            ) AS tmp ----------------------------
      )
      AS rank
FROM Scores s
ORDER BY
      Score DESC
;

Вы могли бы просто использовать count(distinct score) и просто удалите ненужный слой. Однако также обратите внимание, что крайне важно быть очень точным в отношении того, какие столбцы используются для каких целей, поэтому убедитесь, что перед КАЖДОЙ ссылкой на столбец предваряется псевдонимом таблицы или именем таблицы, если псевдоним не был определен. Без исключений.

SELECT
      s.Score
    , (
            SELECT
                  COUNT(DISTINCT s2.Score)
            FROM Scores s2
            WHERE s2.Score >= s.Score
      )
      AS rank
FROM Scores s
ORDER BY
      s.Score DESC
;

пс: rank() это имя функции, поэтому я не очень люблю использовать "rank" в качестве имени столбца, так как это может сбить с толку.

----

для MS SQL Server (извините, неправильно прочитал теги, но оставил это для других читателей)

Я бы рекомендовал избегать использования коррелированных подзапросов в предложении select, это более эффективно делать в from clause и apply operator Доступно в MS SQL Server идеально подходит для этого:

SELECT
      s.Score
    , ca.[rank]
FROM Scores s
CROSS APPLY (
      SELECT
            COUNT(DISTINCT s2.Score) AS [rank]
      FROM Scores s2
      WHERE s2.Score >= s.Score
      ) ca
ORDER BY
      s.Score DESC
;
Другие вопросы по тегам