Выбрать из CTE, используя AS? SQL Server 2008

#sql #sql-server-2008 #common-table-expression

#sql #sql-server-2008 #common-table-expression

Вопрос:

Я пытаюсь преобразовать PostgreSQL в SQL Server. Но этот запрос не работает.

Что я делаю не так? Я пытался добавить точку с запятой ранее С помощью, но безуспешно.

    SELECT 
      member_a AS you, member_b AS mightknow, shared_connection,
      CASE
         WHEN (n1.member_job_country = n2.member_job_country AND n1.member_job_country = n3.member_job_country) THEN 'country in common'
         WHEN (n1.member_unvan_id = n2.member_unvan_id AND n1.member_unvan_id = n3.member_unvan_id) THEN 'unvan in common'
         ELSE 'nothing in common'
      END AS reason
   FROM (
      WITH transitive_closure(member_a, member_b, distance, path_string, direct_connection) AS
        (SELECT 
             member_a, member_b, 1 AS distance,
             CAST(member_a as varchar(MAX))   '.'   CAST(member_b as varchar(MAX))   '.' AS path_string,
             member_b AS direct_connection
         FROM Member_Contact_Edges
         WHERE member_a = 45046 -- set the starting node

         UNION ALL

         SELECT 
             tc.member_a, e.member_b, tc.distance   1,
             CAST(tc.path_string as varchar(MAX))   CAST(e.member_b as varchar(MAX))   '.' AS path_string,
             tc.direct_connection
         FROM Member_Contact_Edges AS e
         JOIN transitive_closure AS tc ON e.member_a = tc.member_b
         WHERE tc.path_string NOT LIKE '%'   CAST(e.member_b as varchar(MAX))   '.%'
         AND tc.distance < 2
        )

   SELECT
       member_a, member_b,direct_connection AS shared_connection
   FROM transitive_closure
   WHERE distance = 2
  ) AS youmightknow
  LEFT JOIN Members AS n1 ON youmightknow.member_a = n1.memberID
  LEFT JOIN Members AS n2 ON youmightknow.member_b = n2.memberID
  LEFT JOIN Members AS n3 ON youmightknow.shared_connection = n3.memberID
  WHERE (n1.member_job_country = n2.member_job_country 
         AND n1.member_job_country = n3.member_job_country)
        OR (n1.member_unvan_id = n2.member_unvan_id 
            AND n1.member_unvan_id = n3.member_unvan_id);
  

Ошибка, которую я получаю:

Сообщение 156, уровень 15, состояние 1, строка 11
Неправильный синтаксис рядом с ключевым словом ‘WITH’.
Сообщение 319, уровень 15, состояние 1, строка 11
Неправильный синтаксис рядом с ключевым словом ‘with’. Если этот оператор является обычным табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен заканчиваться точкой с запятой.
Сообщение 102, уровень 15, состояние 1, строка 34,
неправильный синтаксис рядом с ‘)’.

Вот ссылка; Графики в базе данных — SQL соответствует социальным сетям — Посмотрите на часть facebook suggestion в нижней части статьи.

Заранее спасибо

Ответ №1:

Объявление CTE должно располагаться вверху. Вы также можете объявить несколько CTE и объединить их запятыми, а не смешивать CTE и производные таблицы.

Попробуйте

 ;WITH 
/*First CTE declaration*/
transitive_closure(member_a, member_b, distance, path_string, direct_connection) 
AS
(   
     ...
),
/*Second CTE declaration*/
youmightknow AS
(
SELECT member_a, member_b,direct_connection AS shared_connection
FROM transitive_closure
WHERE distance = 2
)        
SELECT member_a AS you,
...
FROM youmightknow
  

Комментарии:

1. спасибо @Martin, который сейчас работает просто великолепно, и @Michael Ludwig: спасибо за ссылку, это мне очень помогло.

Ответ №2:

Переместите свое определение CTE в начало вашей инструкции SQL. Ключевое слово WITH появляется один раз в начале вашей инструкции, чтобы ввести один или несколько CTE, на которые затем можно ссылаться в следующем SQL. Взгляните на этот пример CTE, он прояснит это для вас.