Конференция "Базы" » Вопрос по SQL [D7, MSSQL]
 
  • nikefest (16.03.12 13:35) [0]
    Помогите, пожалуйста, решить задачку:
    CREATE TABLE T([P] [int] IDENTITY(1,1) NOT NULL)
    CREATE TABLE T1([P1] [int] IDENTITY(1,1) NOT NULL,
    [PT] [int] NOT NULL)
    CREATE TABLE T2([P2] [int] IDENTITY(1,1) NOT NULL,
    [PT] [int] NOT NULL)
    Все P-ключи, РТ-внешние ключи к таблице Т.
    Нужно получить все записи из Т и соответствующие им из Т1 и Т2 в таком виде:
    Р Р1 Р2
    1 111 211
    1 112 NULL
    1 113 NULL
    2 NULL 221
    2 NULL 222
    3 NULL NULL
    4 141 241

    То есть нужно, чтобы данные из Т1 и Т2 не объединялись, а пересекались по полю РТ
  • stas © (16.03.12 15:21) [1]

    select T.P, T1.P1, T2.P2 from
    T
    Left join T1 on T1.PT=T.P
    Left join T2 on T2.PT=T.P


    Как*то так...
  • nikefest (16.03.12 15:43) [2]
    нет нет. это как раз и получается объединение.
    Мне не важно сделать это одним запросом, может быть как-то через процедуры или через несколько вьюшек
  • stas © (16.03.12 15:55) [3]
    Тогда не понял вопроса, покажите как эти данные выглядят в таблицах
  • nikefest (16.03.12 16:34) [4]
    P
    1
    2
    3
    4

    P1   PT
    111  1
    112  1
    113  1
    141  4

    P2    PT
    211   1
    221   2
    222   2
    241   4
  • stas © (16.03.12 16:58) [5]
    тот запрос вернет такой результат как нужно
  • stas © (16.03.12 17:01) [6]
    А нужно чтобы если в табл 2 1 запись чтобы она не дублировалась?
  • nikefest (16.03.12 17:41) [7]

    > А нужно чтобы если в табл 2 1 запись чтобы она не дублировалась?

    да, да. В том-то и дело. Одним запросом это не сделать. Но никак не могу придумать ни процедуру, ни комбинацию вьюшек.
    Может как-то ввести искуственный ключь в Т1 и Т2, чтобы по нему их соединить?...
  • знайка (16.03.12 17:58) [8]
    а кокой критерий того что 211 должна быть именно с 111 а не с 112 или 113? что-то тут не то
  • nikefest (16.03.12 18:13) [9]

    > а кокой критерий того что 211 должна быть именно с 111 а
    > не с 112 или 113? что-то тут не то

    в этом плане нет критериев, это не важно. Просто нужно чтобы для Р выдавалось максимальное число строк из Т1 или Т2, но не сумма Т1 и Т2
  • Германн © (16.03.12 19:27) [10]

    > в этом плане нет критериев, это не важно. Просто нужно чтобы
    > для Р выдавалось максимальное число строк из Т1 или Т2

    outer join
    http://ru.wikipedia.org/wiki/Join_%28SQL%29
    Если мой телепатор угадал :)
  • знайка (16.03.12 19:29) [11]
    как-то так

    select P, NULL as P1, P2  into #R from T left join t2 on t2.PT=t.P

    update #R set P1 = t1.P1 from #R join T1 on t1.PT=#R.P

    insert into #r
    select PT, t1.P1, NULL AS P2
    from t1 where P1 not in (select P1 from #R where #R.P=T1.PT)

    select * from #R

    drop table #R
    ?
    возможно можно еще более проще  ...
  • знайка (16.03.12 19:47) [12]
    хотя наверное тоже не то. :)
  • Johnmen © (16.03.12 21:08) [13]

    > nikefest   (16.03.12 13:35)  

    Вы сами сначала определитесь, какие именно записи надо выдавать из T1 и T2.
    Например.
    T1 - записи абырвалг11 и абырвалг12
    T2 - записи абырвалг21, абырвалг22 и абырвалг23
    Какие из них интересуют? Где критерий?
  • Кщд (16.03.12 23:01) [14]
    >знайка   (16.03.12 19:29) [11]
    можно без ахинеи?)
    автор сам изрядно не в курсе, чего хочет
    не увеличивайте энтропию)
  • turbouser © (17.03.12 18:49) [15]
    тут сам собой напрашивается ОВСФ
  • nikefest (19.03.12 14:32) [16]
    Ну уж я не знаю как еще объяснить что нужно. Т1 и Т2 между собой не связаны никак. Только через таблицу Т. Вот Знайка скорее всего меня понял, попробую его вариант под номером 11
  • Inovet © (19.03.12 14:41) [17]
    > [16] nikefest   (19.03.12 14:32)
    > Т1 и Т2 между собой не связаны никак. Только через таблицу Т.

    Значит заполняешь Т1 и Т2, потом заполняешь их связь в Т.
  • Кщд (20.03.12 08:17) [18]
    >nikefest   (19.03.12 14:32) [16]
    ок.
    почему в выборке есть:
    Р Р1 Р2
    1 111 211

    но нет:
    Р Р1 Р2
    1 112 211
    1 113 211

    ?
  • nikefest (20.03.12 11:36) [19]

    > почему в выборке есть:
    > Р Р1 Р2
    > 1 111 211
    >
    > но нет:
    > Р Р1 Р2
    > 1 112 211
    > 1 113 211


    ну вот пример попроще: Есть таблица футбольных команд Ф, и две таблицы игроков которые пришли в команду ИП и таблица игроков которые ушли из команды ИУ. Естественно что ИП и ИУ связаны между собой только через таблицу Ф. И вот из команды "Дуболомы" ушли Сидоров и Дубов, а пришел Травкин. Нужно вывести эти данные в таком виде:
    Команда           Ушли      Пришли
    "Дуболомы"    Сидоров    Травкин
    "Дуболомы"    Дубов       Null

    Так понятнее может быть будет
  • Anatoly Podgoretsky © (20.03.12 12:00) [20]
    > nikefest  (20.03.2012 11:36:19)  [19]

    Как Травкин связан с Сидоров?
  • nikefest (20.03.12 12:40) [21]

    > Как Травкин связан с Сидоров?

    только командой.
  • Anatoly Podgoretsky © (20.03.12 12:42) [22]
    Надо ли спрашивать какой и DDL
  • nikefest (20.03.12 12:43) [23]

    > select P, NULL as P1, P2  into #R from T left join t2 on
    > t2.PT=t.P
    >
    > update #R set P1 = t1.P1 from #R join T1 on t1.PT=#R.P
    >
    > insert into #r
    > select PT, t1.P1, NULL AS P2
    > from t1 where P1 not in (select P1 from #R where #R.P=T1.
    > PT)
    >
    > select * from #R
    >
    > drop table #R

    Спасибо большое, Знайка. Этот код работает :)
    Я пытался колупаться с искуственным айдишником и заполнять таблицу через курсоры. По-моему проще некуда :)
  • Кщд (20.03.12 14:53) [24]
    >nikefest   (20.03.12 12:43) [23]
    последний раз.
    ответьте себе на вопрос, почему так:
    Команда           Ушли      Пришли
    "Дуболомы"    Сидоров    Травкин
    "Дуболомы"    Дубов       Null

    а не так:
    Команда           Ушли      Пришли
    "Дуболомы"    Сидоров    Null
    "Дуболомы"    Дубов       Травкин

    и вместо того, чтобы бестолково "колупаться с искуственным айдишником и заполнять таблицу через курсоры", почитайте хоть что-нибудь по SQL - например, "Understanding SQL"
  • nikefest (20.03.12 16:29) [25]

    > ответьте себе на вопрос, почему так:
    > Команда           Ушли      Пришли
    > "Дуболомы"    Сидоров    Травкин
    > "Дуболомы"    Дубов       Null
    >
    > а не так:
    > Команда           Ушли      Пришли
    > "Дуболомы"    Сидоров    Null
    > "Дуболомы"    Дубов       Травкин

    Да что ж вы такой непонятливый
    Отвечаю последний раз на ВАШ вопрос: Никакой разницы нет!!!!. Второй вариант тоже допустим. Главное чтобы Травкин два раза не появлялся.
    Вы наверное прочитали все про SQL, поэтому задаете один и тот же вопрос по нескольку раз, вместо того чтобы попытаться решить задачку
  • Германн © (20.03.12 16:48) [26]

    >
    > Да что ж вы такой непонятливый
    > Отвечаю последний раз на ВАШ вопрос: Никакой разницы нет!
    > !!!. Второй вариант тоже допустим. Главное чтобы Травкин
    > два раза не появлялся.

    Так почему бы тогда не получать результат двумя разными кусками
    1.
    Команда           Ушли    
    "Дуболомы"    Сидоров  
    "Дуболомы"    Дубов      

    2.
    Команда        Пришли
    "Дуболомы"    Травкин

    ???
  • nikefest (20.03.12 17:42) [27]

    > Так почему бы тогда не получать результат двумя разными
    > кусками
    > 1.
    > Команда           Ушли    
    > "Дуболомы"    Сидоров  
    > "Дуболомы"    Дубов      
    >
    > 2.
    > Команда        Пришли
    > "Дуболомы"    Травкин

    Ну, а дальше? нужна ведь одна таблица для отображения, а не две
  • Германн © (20.03.12 17:49) [28]

    > Ну, а дальше? нужна ведь одна таблица для отображения, а
    > не две

    А понял. Нет бога, кроме TDBGrid :)
  • Кщд (21.03.12 08:02) [29]
    >nikefest   (20.03.12 11:36) [19]
    1. задачу сформулировать не в состоянии;
    2. знаний и желания их получить ровно ноль;
    3. к советам, данным в этой ветке неоднократно и разными пользователями, прислушаться желания нет.

    вывод неутешителен: бессменный капитан команды "Дуболомы")
  • Кщд (21.03.12 08:02) [30]
    ах, да:


    with t as (
             select 1 p from dual
             union all
             select 2 from dual          
             union all
             select 3 from dual
             union all
             select 4 from dual
             
             ),
        t1 as (
             select t1.pt, t1.p1,
                    row_number() over (partition by t1.pt order by t1.p1) rn
             from
                 (    
                 select 111 p1, 1 pt from dual
                 union all
                 select 112, 1 from dual
                 union all
                 select 113, 1 from dual
                 union all
                 select 141, 4 from dual              
                 ) t1
              ),
        t2 as (
             select t2.pt, t2.p2,
                    row_number() over (partition by t2.pt order by t2.p2) rn
             from
                 (          
                 select 211 p2, 1 pt from dual
                 union all
                 select 221, 2 from dual
                 union all
                 select 222, 2 from dual
                 union all
                 select 241, 4 from dual              
                 ) t2
              )          
    select t.p, m.p1, m.p2
    from t t    
          left join (
                    select coalesce(t1.pt, t2.pt) pt, t1.p1 p1, t2.p2 p2
                    from t1 t1
                           full join t2 t2
                             on t1.pt = t2.pt
                                and t1.rn = t2.rn
                    ) m
            on t.p = m.pt
    order by t.p        

  • Anatoly Podgoretsky © (21.03.12 08:15) [31]
    Он замучается это переводить на MS SQL
  • Inovet © (21.03.12 10:47) [32]
    > [25] nikefest   (20.03.12 16:29)
    > Отвечаю последний раз на ВАШ вопрос: Никакой разницы нет!
    > !!!. Второй вариант тоже допустим. Главное чтобы Травкин
    > два раза не появлялся.

    Ты занят ерундой и запутыванием пользователя, а начал с запутывания себя. Похожий вид в отчётах иногда делается просто как вариант печати в 2, 3, N колонок с разными заголовками. Но БЕЗ связи их. В твоём случае будет как-то так

    Команда "Дуболомы"

    Ушли       Пришли    В наличии
    Сидоров    Травкин   Козлов
    Дубов                Быков
                        Баранов

    Команда "Лесопилы"
    Ушли          Пришли     В наличии
    Князь         Синий      Кокс
    Паша Северный Выдра      Жарый
                 Бульдозер  Шпала
  • Кщд (21.03.12 11:07) [33]
    >Inovet ©   (21.03.12 10:47) [32]
    оставьте, это бесполезно - он не понимает
  • nikefest (21.03.12 11:13) [34]
    Удалено модератором
  • nikefest (21.03.12 11:19) [35]

    > Ты занят ерундой и запутыванием пользователя, а начал с
    > запутывания себя. Похожий вид в отчётах иногда делается
    > просто как вариант печати в 2, 3, N колонок с разными заголовками.
    >  Но БЕЗ связи их. В твоём случае будет как-то так

    Это не отчет. Это экранная форма, в которой нужно дальше манипулировать данными - типа групировок и промежуточных итогов.
    Поверте, все варианты просто отобразить такую информацию уже реализованы. Просто нужен еще вот такой замороченный вариант
  • Inovet © (21.03.12 11:26) [36]
    > [35] nikefest   (21.03.12 11:19)
    > Просто нужен еще вот такой замороченный вариант

    Просто, когда хотят странного, возникают подозрения в неправильной реализации. Нормальным было бы отобразить 1 мастер и 2 детейла. Ну может зачем-то и так криво надо, не знаю.
  • nikefest (21.03.12 11:41) [37]

    > Просто, когда хотят странного, возникают подозрения в неправильной
    > реализации. Нормальным было бы отобразить 1 мастер и 2 детейла.
    >  Ну может зачем-то и так криво надо, не знаю.

    Да это понятно, и уже сделано, причем в двух вариантах. Это финансы и вот им нужно еще "как в экселе".
  • Кщд (21.03.12 12:04) [38]
    >nikefest   (21.03.12 11:13) [34]
    >Кщд   (21.03.12 08:02) [30]
    клиника...
 
Конференция "Базы" » Вопрос по SQL [D7, MSSQL]
Есть новые Нет новых   [134431   +10][b:0][p:0.003]