简体   繁体   English

一个简单的Sql Select查询

[英]A Simple Sql Select Query

I know I am sounding dumb but I really need help on this. 我知道我听起来很蠢,但是我确实需要帮助。

I have a Table (let's say Meeting) which Contains a column Participants. 我有一个表(比方说会议),其中包含一个列参与者。 The Participants dataType is varchar(Max) and it stores Participant's Ids in comma separated form like 1,2. 参与者数据类型为varchar(Max),它以逗号分隔的形式(如1,2)存储参与者的ID。

Now my problem is I am passing a parameter called @ParticipantsID in my Stored Procedure and want to do something like this: 现在我的问题是我在存储过程中传递了一个名为@ParticipantsID的参数,并想要执行以下操作:

Select Participants from Meeting where Participants in (@ParticipantsID)

Unfortunately I am missing something crucial here. 不幸的是,我在这里错过了一些至关重要的事情。

Can some one point that out? 可以指出一点吗?

I've been there before... I changed the DB design to have one record contain a single reference to the other table. 我之前去过那里。。。我更改了数据库设计,以使一个记录包含对另一张表的单个引用。 If you can't change your DB structures and you have to live with this, I found this solution on CodeProject . 如果您不能更改数据库结构,而必须忍受这一点,那么我会在CodeProject上找到此解决方案。

New Function 新功能

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

New Sproc 新存储

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

Your table is not normalized. 您的表未规范化。 If you want to query for individual participants, they should be split into their own table, along the lines of: 如果要查询单个参与者,则应将他们拆分为自己的表,方法如下:

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

Otherwise, you have to resort to all sorts of trickery (what I call SQL gymnastics) to find out what you want. 否则,您必须采取各种手段(我称之为SQL体操)来找出您想要的东西。 That trickery never scales well - your queries become slow very quickly as the table grows. 这种诡计永远无法很好地扩展-随着表的增长,查询变得非常缓慢。

With a properly normalized database, the queries can remain fast well into the multi-millions of records (I work with DB2/z where we are used to truly huge tables). 使用正确规范化的数据库,查询可以很好地保持在数以百万计的记录中(我使用DB2 / z来处理真正的大表)。

There are valid reasons for sometimes reverting to second normal form (or even first) for performance but that should be a very hard thought out decision (and based on actual performance data). 有充分的理由有时会恢复到第二范式(甚至是第一范式)以提高性能,但这应该是一个很难考虑的决定(并基于实际性能数据)。 All databases should initially start of in 3NF. 所有数据库最初应从3NF开始。

You would not typically organise your SQL database in quite this way. 您通常不会以这种方式组织SQL数据库。 What you are describing are two entities (Meeting & Participant) that have a one-to-many relationship. 您要描述的是两个具有一对多关系的实体(会议和参与者)。 ie a meeting can have zero or more participants. 即会议可以有零个或多个参与者。 To model this in SQL you would use three tables: a meeting table, a participant table and a MeetingParticipant table. 要在SQL中对此建模,您将使用三个表:一个会议表,一个参与者表和一个MeetingParticipant表。 The MeetingParticipant table holds the links between meetings & participants. MeetingParticipant表包含会议和参与者之间的链接。 So, you might have something like this (excuse any sql syntax errors) 因此,您可能会遇到类似这样的情况(请注意任何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
)

To populate these tables you would first create some Participants: 要填充这些表,您首先需要创建一些参与者:

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')

and create a Meeting or two insert into Meeting(MeetingID, Name, Location) values(10, 'SQL Training', 'Room 1') insert into Meeting(MeetingID, Name, Location) values(11, 'SQL Training', 'Room 2') 并在Meeting(MeetingID,Name,Location)值(10,'SQL Training','Room 1')中创建一两个Meeting插入并在Meeting(MeetingID,Name,Location)值(11,'SQL Training',' 2'室)

and now add some participants to the meetings 现在将一些参与者添加到会议中

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)

Now you can select all the meetings and the participants for each meeting with 现在,您可以选择所有会议以及每个会议的参与者

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

the above should produce 以上应该产生

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    

If you want to find out all the meetings that "Dick Smith" is in you would write something like this 如果您想找出“迪克·史密斯”参加的所有会议,则可以这样写:

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

and get 并得到

MeetingID Location
10        Room 1
11        Room 2

I have omitted important things like indexes, primary keys and missing attributes such as meeting dates, but it is clearer without all the goo. 我已经省略了重要的内容,例如索引,主键和缺少的属性(例如会议日期),但是没有所有的麻烦,事情就更清楚了。

If I understand your question correctly, you are trying to pass in a comma separated list of participant ids and see if it is in your list. 如果我正确理解了您的问题,则您尝试传递以逗号分隔的参与者ID列表,并查看它是否在列表中。 This link lists several ways to do such a thing" 此链接列出了执行此操作的几种方法”

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

codezy.blogspot.com codezy.blogspot.com

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

where 12 is the ID you are looking for.... 其中12是您要查找的ID。...

Ugly, what a nasty model. 丑陋,令人讨厌的模型。

If you store the participant ids in a comma-separated list (as text) in the database, you cannot easily query it (as a list) using SQL. 如果将参与者ID存储在数据库中以逗号分隔的列表(作为文本)中,则无法使用SQL轻松查询它(作为列表)。 You would have to resort to string-operations. 您将不得不求助于字符串运算。

You should consider changing your schema to use another table to map meetings to participants: 您应该考虑更改架构以使用另一个表将会议映射到参与者:

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

That table would have multiple rows per meeting (one for each participant). 该表每个会议将有多行(每个参与者一个)。 You can then query that table for individual participants, or number of participants, and such. 然后,您可以在该表中查询单个参与者或参与者数量等。

If participants is a separate data type you should be storing it as a child table of your meeting table. 如果参与者是单独的数据类型,则应将其存储为会议表的子表。 eg 例如

  • MEETING 会议
    • PARTICIPANT 1 参加者1
    • PARTICIPANT 2 参加者2
    • PARTICIPANT 3 参加者3

Each participant would hold the meeting ID so you can do a query 每个参与者都将持有会议ID,以便您进行查询

SELECT * FROM participants WHERE meeting_id = 1 SELECT * FROM参与者WHERE Meeting_id = 1

However, if you must store a comma separated list (for some external reason) then you can do a string search to find the appropriate record. 但是,如果您必须存储逗号分隔的列表(出于某种外部原因),则可以进行字符串搜索以找到适当的记录。 This would be a very inefficient way to do a query though. 但是,这将是一种非常低效的查询方法。

That is not the best way to store the information you have. 这不是存储您拥有的信息的最佳方法。

If it is all you have got then you need to be doing a contains (not an IN). 如果仅此而已,那么您需要执行一个包含(而不是IN)。 The best answer is to have another table that links Participants to Meetings. 最好的答案是使用另一个表将与会者与会议链接起来。

Try SELECT Meeting, Participants FROM Meeting CONTAINS(Participants, @ParticipantId) 尝试SELECT Meeting,来自会议内容的参与者(参与者,@ ParticipantId)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM