2009-04-09 5 views
1

Я знаю, что я глупо, но мне действительно нужна помощь в этом.Простой запрос выбора Sql

У меня есть таблица (скажем, встреча), которая содержит столбец «Участники». Данные данных участников - это varchar (Max), и он хранит идентификаторы Участника в форме, разделенной запятыми, например, 1,2.

Теперь моя проблема я передаю параметр называется @ParticipantsID в моей хранимой процедуре и хочу сделать что-то вроде этого:

Select Participants from Meeting where Participants in (@ParticipantsID) 

К сожалению, я что-то решающее здесь отсутствую.

Может какой-то один пункт это?

+0

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

+0

@Frank - Я видел этот материал раньше, и это было не домашнее задание ... Дайте человеку перерыв ... – RSolberg

ответ

1

Если я правильно понял ваш вопрос, вы пытаетесь передать список идентификаторов участников, разделенных запятыми, и посмотреть, находится ли он в вашем списке. Эта ссылка перечисляет несколько способов, чтобы сделать такую ​​вещь»

[http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm][1]

codezy.blogspot.com

+0

В моем случае в столбце «Участники» есть CSV, и я передаю только один Участник ID – 2009-04-09 05:24:39

+0

в том, что Случай, который должен работать, я думаю, если вы перевернете свою статью вокруг: Выберите участников с совещания, где @ Участники Форума Участники – Codezy

0

Если вы храните участника идентификаторы в виде списка разделенных запятыми (как текст) в базе данных, вы не можете легко запросить его (в виде списка) с помощью SQL Вам придется прибегнуть к строковым операциям

вы должны рассмотреть вопрос о смене схемы использовать другую таблицу для отображения встреч участников:..

create table meeting_participants (
    meeting_id integer not null , -- foreign key 
    participant_id integer not null 
); 

Эта таблица будет иметь несколько рядов на встречу (по одному для каждого участника). Затем вы можете запросить эту таблицу для отдельных участников или числа участников и т. Д.

0

Если участники - это отдельный тип данных, вы должны хранить его в качестве дочерней таблицы таблицы собраний. например

  • ВСТРЕЧА
    • УЧАСТНИК 1
    • УЧАСТНИК 2
    • УЧАСТНИК 3

Каждый участник будет проводить идентификатор собрания, так что вы можете сделать запрос

ВЫБЕРИТЕ * ОТ участников WHERE meeting_id = 1

Однако, если вы должны сохранить список, разделенный запятой (по какой-то внешней причине), вы можете выполнить строковый поиск, чтобы найти соответствующую запись. Однако это было бы очень неэффективным способом сделать запрос.

0

Это не лучший способ хранить информацию у вас есть.

Если это все, что у вас есть, тогда вам нужно делать сложения (а не IN). Лучший ответ - иметь еще одну таблицу, которая связывает участников с собраниями.

Постарайся ВЫБРАТЬ совещание, участники из собрания СОДЕРЖИТ (Участники, @ParticipantId)

3

Я был там раньше ... Я изменил дизайн БД, чтобы иметь одну запись содержит ни одной ссылки на другую таблицу. Если вы не можете изменить свои структуры БД, и вам нужно жить с этим, я нашел это решение на CodeProject.

Новая функция

IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID(’UF_CSVToTable’)) 
DROP FUNCTION UF_CSVToTable 
GO 

CREATE FUNCTION UF_CSVToTable 
(
@psCSString VARCHAR(8000) 
) 
RETURNS @otTemp TABLE(sID VARCHAR(20)) 
AS 
BEGIN 
DECLARE @sTemp VARCHAR(10) 

WHILE LEN(@psCSString) > 0 
BEGIN 
    SET @sTemp = LEFT(@psCSString, ISNULL(NULLIF(CHARINDEX(',', @psCSString) - 1, -1), 
        LEN(@psCSString))) 
    SET @psCSString = SUBSTRING(@psCSString,ISNULL(NULLIF(CHARINDEX(',', @psCSString), 0), 
           LEN(@psCSString)) + 1, LEN(@psCSString)) 
    INSERT INTO @otTemp VALUES (@sTemp) 
END 

RETURN 
END 
Go 

Новый Sproc

SELECT * 
FROM 
    TblJobs 
WHERE 
    iCategoryID IN (SELECT * FROM UF_CSVToTable(@sCategoryID)) 
+1

Что он сказал. :) используйте функцию таблицы, чтобы разобрать список, разделенный запятыми. –

1
SELECT * FROM Meeting WHERE Participants LIKE '%,12,%' OR Participants LIKE '12,%' OR Participants LIKE '%,12' 

где 12 это идентификатор вы ищете ....

Гадкий, какой неприятная модель.

3

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

Meeting 
    MeetingId primary key 
    Other stuff 
Persons 
    PersonId primary key 
    Other stuff 
Participants 
    MeetingId foreign key Meeting(MeetingId) 
    PersonId foreign key Persons(PersonId) 
    primary key MeetingId,PersonId 

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

С правильно нормированной базой данных запросы могут быстро сохраняться в многомиллионных записях (я работаю с DB2/z, где мы привыкли к действительно огромным таблицам).

Имеются веские причины для того, чтобы иногда возвращаться к второй нормальной форме (или даже первой) для производительности, но это должно быть очень сложное продуманное решение (и основано на фактических данных о производительности). Сначала все базы данных должны начинаться с 3NF.

3

Обычно вы не организовываете свою базу данных SQL таким образом. То, что вы описываете, - это два объекта (встреча & Участник), которые имеют отношения «один ко многим». то есть собрание может иметь ноль или более участников. Чтобы смоделировать это в SQL, вы должны использовать три таблицы: таблицу собраний, таблицу участников и таблицу MeetingParticipant. Таблица MeetingParticipant содержит ссылки между встречами & участников.Таким образом, вы могли бы иметь что-то вроде этого (извините любые SQL синтаксических ошибок)

create table Meeting 
(
    MeetingID int, 
    Name varchar(50), 
    Location varchar(100) 
) 

create table Participant 
(
    ParticipantID int, 
    FirstName varchar(50), 
    LastName varchar(50) 
) 

create table MeetingParticipant 
(
    MeetingID int, 
    ParticipantID int 
) 

Для заполнения этих таблиц вы бы сначала создать несколько участников:

insert into Participant(ParticipantID, FirstName, LastName) values(1, 'Tom', 'Jones') 
insert into Participant(ParticipantID, FirstName, LastName) values(2, 'Dick', 'Smith') 
insert into Participant(ParticipantID, FirstName, LastName) values(3, 'Harry', 'Windsor') 

и создать собрание или два вставки в собрании (MeetingID, Name, Location) (10, 'SQL Training', 'Room 1') Вставить в значения Meeting (MeetingID, Name, Location) (11, 'SQL Training', 'Room 2')

и теперь добавьте некоторых участников на собрания

insert into MeetingParticipant(MeetingID, ParticipantID) values(10, 1) 
insert into MeetingParticipant(MeetingID, ParticipantID) values(10, 2) 
insert into MeetingParticipant(MeetingID, ParticipantID) values(11, 2) 
insert into MeetingParticipant(MeetingID, ParticipantID) values(11, 3) 

Теперь вы можете выбрать все встречи и участников для каждой встречи с

select m.MeetingID, p.ParticipantID, m.Location, p.FirstName, p.LastName 
from Meeting m 
    join MeetingParticipant mp on m.MeetingID=mp.MeetingID 
    join Participant p on mp.ParticipantID=p.ParticipantID 

выше следует производить

MeetingID ParticipantID Location FirstName LastName 
10  1    Room 1 Tom  Jones 
10  2    Room 1 Dick  Smith 
11  2    Room 2 Dick  Smith 
11  3    Room 2 Harry  Windsor  

Если вы хотите узнать все встречи, которые " Дик Смит ", вы напишете что-то вроде этого

select m.MeetingID, m.Location 
from Meeting m join MeetingParticipant mp on m.MeetingID=mp.ParticipantID 
where 
    mp.ParticipantID=2 

и получить

MeetingID Location 
10  Room 1 
11  Room 2 

Я опустил важные вещи, как индексы, первичные ключи и отсутствующие атрибуты, такие как встречи даты, но понятнее без всякой слизи.

Смежные вопросы