How can i remove duplicates from this Sql Server Table? - sql

I have a single table in the Sql Server 2008 r2 DB. Every few seconds I import data into this table. At one point, the import was failing, so it was constantly importing the same data, creating duplicates. (basically, if the import read 20 lines, imported 19 and failed on 20 .. then those 19 were not in a transaction .. and thus got inserted).
Anyways, I'm trying to figure out how I can I remove all the duplicates and just the first (original) inserted row?
Here's the table schema - and please note that there's a few nullable fields.
CREATE TABLE [dbo].[LogEntries](
[LogEntryId] [int] IDENTITY(1,1) NOT NULL,
[GameFileId] [int] NOT NULL,
[CreatedOn] [datetimeoffset](7) NOT NULL,
[EventTypeId] [tinyint] NOT NULL,
[Message] [nvarchar](max) NULL,
[Code] [int] NULL,
[Violation] [nvarchar](100) NULL,
[ClientName] [nvarchar](100) NULL,
[ClientGuid] [nvarchar](50) NULL,
[ClientGuidReversed] [nvarchar](50) NULL,
[ClientIpAndPort] [nvarchar](50) NULL,
CONSTRAINT [PK_LogEntries] PRIMARY KEY CLUSTERED
(
[LogEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Cheers :)
UPDATE: What are Duplicates (in this case?)
Damn sorry. forgot to define a duplicate.
The LogEntryId is unique, so ignore that piece of info (it's not imported). all the rest of the data is imported. Here's two rows of data that are identical.
6459749 39 2010-11-05 00:00:25.0000000 +11:00 6 Violation (MULTIHACK) #70805 70805 MULTIHACK angelb aeda202c22ed41f7301d0673647c55d8 8d55c7463760d1037f14de22c202adea 220.246.157.194:57133
6459766 39 2010-11-05 00:00:25.0000000 +11:00 6 Violation (MULTIHACK) #70805 70805 MULTIHACK angelb aeda202c22ed41f7301d0673647c55d8 8d55c7463760d1037f14de22c202adea 220.246.157.194:57133
and to compare this to the top 5 ordered by desc
6505931 40 2010-11-08 23:39:16.0000000 +11:00 4 NULL NULL NULL Zaphrolio 69ae1bfea616c244e5c223e51d5ceb8e e8bec5d15e322c5e442c616aefb1ea96 175.38.209.80:10000
6505930 39 2010-11-08 23:39:04.0000000 +11:00 3 NULL NULL NULL imBakedAsBro 8cf1b3b6a389229fa4adeec07dc087ce ec780cd70ceeda4af922983a6b3b1fc8 110.175.83.45:10000
6505929 39 2010-11-08 23:39:03.0000000 +11:00 2 NULL NULL NULL imBakedAsBro NULL NULL 110.175.83.45:10000
6505928 80 2010-11-08 23:39:04.0000000 +11:00 4 NULL NULL NULL Asmo74 5ccf5ee85a6cf08da563bdcbfe75351d d15357efbcdb365ad80fc6a58ee5fcc5 61.68.212.231:50273
6505927 80 2010-11-08 23:39:03.0000000 +11:00 4 NULL NULL NULL McJellyfish c48218542918bec900a331a81e0a9d05 50d9a0e18a133a009ceb81924581284c 60.225.3.2:10000

with cte as (
select row_number() over (
partition by
[GameFileId]
, [CreatedOn]
, [EventTypeId]
, [Message]
, [Code]
, [Violation]
, [ClientName]
, [ClientGuid]
, [ClientGuidReversed]
, [ClientIpAndPort]
order by [LogEntryId]) as rn
from LogEntries)
delete from cte
where rn > 1;

in the abscence of any other information, UNION ALL is normally a good trick to blat out dupes
select * from table
union
select * from table
Edited to reflect typo in comment...

Related

How to create a table with 2 primary key in SQL Server? [duplicate]

This question already has answers here:
How to set (combine) two primary keys in a table
(4 answers)
Closed 5 years ago.
I want to insert a record like below
ID VendorName RequestNo VendorCode ChequeDateSearch Description StoreID
-------------------------------------------------------------------------------------
1 John 1011 1021 2017-10-25 00:00:00.000 descr 6000
2 michael 1011 1022 2017-10-25 00:00:00.000 descr 6000
3 Abraham 1011 1023 2017-10-25 00:00:00.000 descr 6000
Note
It should not accept duplicate VendorCode for same RequestNo
In My table ID,RequestNo and VendorCode should be primary key. ID is auto increment, and the RequestNo and VendorCode is user specification
CREATE TABLE [dbo].[CheqVendorSearch](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[VendorName] [nvarchar](max) NULL,
[RequestNo] [varchar](50) Not NULL,
[VendorCode] [varchar](50) NOT NULL,
[ChequeDateSearch] [datetime] NULL,
[Description] [nvarchar](max) NULL,
[StoreID] [varchar](10) NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC,
[RequestNo] ASC,
[VendorCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
But this table is accepting the duplicate for RequestNo and VendorCode like below
ID VendorName RequestNo VendorCode ChequeDateSearch Description StoreID
-------------------------------------------------------------------------------------
1 John 1011 1023 2017-10-25 00:00:00.000 descr 6000
2 michael 1011 1023 2017-10-25 00:00:00.000 descr 6000
3 Abraham 1011 1023 2017-10-25 00:00:00.000 descr 6000
I believe that you just need the UNIQUE constraint in your table definition.
CREATE TABLE [dbo].[CheqVendorSearch](
[ID] [bigint] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[VendorName] [nvarchar](max) NULL,
[RequestNo] [varchar](50) Not NULL,
[VendorCode] [varchar](50) NOT NULL,
[ChequeDateSearch] [datetime] NULL,
[Description] [nvarchar](max) NULL,
[StoreID] [varchar](10) NULL,
CONSTRAINT UQ_vendor_request UNIQUE
(
[RequestNo] ,
[VendorCode] ASC
)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
The major problem in your solution is that each row is uniquely identified by the ID, therefore, it is useless to have RequestNo and VendorCode as a part of the primary key.
You are trying to make a Composite Primary key.
The Composite Primary key enforces to make the combination of Prime Attribute(ID, RequestNo and VendorCode) to be unique. To make RequestNo and VendorCode to be unique too, you have to add Unique Clause on both of them.
CREATE TABLE [dbo].[CheqVendorSearch](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[VendorName] [nvarchar](max) NULL UNIQUE,
[RequestNo] [varchar](50) Not NULL UNIQUE,
[VendorCode] [varchar](50) NOT NULL,
[ChequeDateSearch] [datetime] NULL,
[Description] [nvarchar](max) NULL,
[StoreID] [varchar](10) NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC,
[RequestNo] ASC,
[VendorCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
You define the PK with ID, RequestNo and VendorCode - therefore your mentioned example is not treated as duplicate. However, remove the ID from the PK and it should work fine. Since ID is populated by identity, this should be no problem. If for one reason or the other you have to insert data via identity_insert I suggest to add a unique key to ypur table covering the column ID only.
A composite key apply a unique value for the combination of the 3 columns, not each column individually (1,John,1011) is unique from (2,Michael,1011). You need to add a unique key on the RequestNo column if you want that to be unique too. On a side note have varchar data types as a PK isn't always a good idea and can RequestNo not be an int?

SQL Descending ordered LEFT JOIN subquery issue

I have the following query.
SELECT r1.*,
r2.vlag54,
r2.vlag55
FROM [rxmon].[dbo].[a] AS r1
LEFT JOIN [rxmon].[dbo].[b] AS r2
ON r2.artikelnummer = r1.drug_id
LEFT JOIN (SELECT *
FROM [rxmon].[dbo].[c]) AS r3
ON r3.pid = r1.patient_id
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
AND r1.patient_id = 7092425
AND obx_value < CASE
WHEN r2.vlag54 = 1 THEN 30
WHEN r2.vlag55 = 1 THEN 50
END
AND r2.vlag54 = CASE
WHEN r3.obx_value < 30 THEN 1
ELSE 0
END
AND r2.vlag55 = CASE
WHEN r3.obx_value BETWEEN 30 AND 50 THEN 1
ELSE 0
END
ORDER BY obx_datetime DESC;
The problem is that table C can contain multiple records based on de PID join. This generates the same records because of the multiple records on table C.
The table C needs to e joined as the latest record only so just 1 of C. That way the table A record will not be repeated.
I tried TOP 1 and order by but that can't be used in subquery.
-- TABLE A
CREATE TABLE [dbo].[A]
[EVS_MO_ID] [bigint] NOT NULL,
[DRUG_ID] [varchar](50) NOT NULL,
[ATC_CODE] [varchar](15) NULL,
[DRUG_NAME] [varchar](1024) NULL,
[PATIENT_ID] [varchar](50) NOT NULL,
[PATIENT_LOCATION] [varchar](10) NULL,
[MO_DATE] [datetime2](7) NOT NULL,
[MO_START_DATE] [datetime2](7) NOT NULL,
[MO_STOP_DATE] [datetime2](7) NULL,
[ROUTE] [varchar](50) NULL,
[MEDICATION_CONTAINER] [smallint] NULL,
[PRESCRIBING_DOCTOR_NAME] [varchar](50) NULL,
[PRESCRIBING_DOCTOR_SURNAME] [varchar](50) NULL,
[MO_ACTIVE] [bit] NOT NULL,
CONSTRAINT [PK_MedicationOrders] PRIMARY KEY CLUSTERED
(
[EVS_MO_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[A]
VALUES
(5411409,'97941689', 'B01AB06','NADROPARINE 0.8ML','7092425','ANBC', '2015-12-15 20:58:06.2030000',
'2015-12-16 00:00:00.0000000', '', 'IV', 1, 'GEORGE','LAST', 1);
-- TABLE B
CREATE TABLE [dbo].[B](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ARTIKELNUMMER] [varchar](50) NOT NULL,
[VLAG54] [bit] NULL,
[VLAG55] [bit] NULL CONSTRAINT [DF_Table_1_VLAG50] DEFAULT ((0)),
[VLAG100] [bit] NULL CONSTRAINT [DF_ArtikelVlaggen_VLAG100] DEFAULT ((0)),
CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[B]
([ARTIKELNUMMER]
,[VLAG54]
,[VLAG55]
,[VLAG100])
VALUES
('97941689', 1,0,1);
-- TABLE C
CREATE TABLE [dbo].[C](
[ID] [int] IDENTITY(1,1) NOT NULL,
[OBX_DATETIME] [datetime2](7) NOT NULL,
[PID] [int] NOT NULL,
[DEPARTMENT] [varchar](8) NOT NULL,
[OBX_ID] [int] NOT NULL,
[OBX_VALUE] [decimal](5, 2) NOT NULL,
[OBX_UNITS] [varchar](10) NULL,
[REF_RANGE] [varchar](40) NULL,
[FLAG] [varchar](2) NULL,
CONSTRAINT [PK_C] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[C]
([OBX_DATETIME]
,[PID]
,[DEPARTMENT]
,[OBX_ID]
,[OBX_VALUE]
,[OBX_UNITS]
,[REF_RANGE]
,[FLAG])
VALUES
('2015-12-15 14:01:00.0000000',7092425, '8NAH', 20937, 27.00, 'mL/min', '> 60', 'L');
INSERT INTO [dbo].[C]
([OBX_DATETIME]
,[PID]
,[DEPARTMENT]
,[OBX_ID]
,[OBX_VALUE]
,[OBX_UNITS]
,[REF_RANGE]
,[FLAG])
VALUES
('2015-12-15 06:30:00.0000000',7092425, '6ZPA', 20937, 28.00, 'mL/min', '> 60', 'L');
This will order them by OBX_DATETIME and take only the first one:
...
LEFT JOIN (
SELECT pid, obx_id, obx_datetime, obx_value
, n = ROW_NUMBER() over(PARTITION BY pid ORDER BY obx_datetime desc)
FROM [rxmon].[dbo].[c]
) AS r3
ON r3.pid = r1.patient_id and r3.n = 1
...
If OBX_DATETIME are inserted incrementaly (newer date only), you can order by ID instead.
This SQL Fiddle with your query and sample data/tables returns 2 rows: http://sqlfiddle.com/#!3/df36c/2/0
This SQL Fiddle with the new subquery returns 1 row: http://sqlfiddle.com/#!3/df36c/1/0
You are using a LEFT JOIN on r3 but have also have r3 in your WHERE clause with equal operator:
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
It will remove NULL value from the left join on r3. Perhaps you should also move it to the sub query or use INNER JOIN.
You should also avoind using the DB name in your query unless this query is run from another DB on the same server. This will be fine:
SELECT ... FROM [dbo].[a] AS r1 ...
Using SELECT * is also a bad habit. You should list only the columns your code will use.
try this.... #Shift
SELECT r1.*,
r2.vlag54,
r2.vlag55
FROM [dbo].[a] AS r1
LEFT JOIN [dbo].[b] AS r2
ON r2.artikelnummer = r1.drug_id
LEFT JOIN (
SELECT
ROW_NUMBER() OVER (PARTITION BY pid ORDER BY id DESC) RN,
c.*
FROM C
) r3
ON r3.pid = r1.patient_id AND r3.RN = 1
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
AND r1.patient_id = 7092425
AND obx_value < CASE
WHEN r2.vlag54 = 1 THEN 30
WHEN r2.vlag55 = 1 THEN 50
END
AND r2.vlag54 = CASE
WHEN r3.obx_value < 30 THEN 1
ELSE 0
END
AND r2.vlag55 = CASE
WHEN r3.obx_value BETWEEN 30 AND 50 THEN 1
ELSE 0
END
ORDER BY obx_datetime DESC;

Foreign key from one column to another column contained in multiple column primary key

I try to create a foreign key between one column to two-column primary key and SQL Server refused that. Why ?
I have a table to store my wording in different languages and a country table.
ref.SystemLabels
--------------
--> [Id] int
| [IdLanguage] int
| Label nvarchar(200)
| Keywords nvarchar(200)
|
| ref.Countries
| --------------
| [Id]
--> IdSystemLabel
IsoCode
In my mind, it's very logic but I don't understand why SQL Server doesn't understand or accept my logic ^^.
If anyone can help me about this.
NOTE I think in another way, I will create an index on the IdSystemLabel despite of a foreign key.
EDIT: As you ask me, please see my SQL code for tables
Table SystemLanguages
CREATE TABLE [ref].[SystemLanguages](
[Id] [int] NOT NULL,
[IdSystemLabel] [int] NOT NULL,
[IsoCode] [nchar](2) NOT NULL,
[Enabled] [bit] NOT NULL,
CONSTRAINT [PK_SystemLanguages] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [ref].[SystemLanguages] ADD CONSTRAINT [DF_SystemLanguages_Enabled] DEFAULT ((0)) FOR [Enabled]
GO
Table SystemLabels
CREATE TABLE [ref].[SystemLabels](
[Id] [int] NOT NULL,
[IdLanguage] [int] NOT NULL,
[Label] [nvarchar](max) NOT NULL,
[Keywords] [nvarchar](200) NULL,
[CreatedAt] [datetime] NOT NULL,
[UpdatedAt] [datetime] NULL,
[Group] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_SystemLabels] PRIMARY KEY CLUSTERED
(
[Id] ASC,
[IdLanguage] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [ref].[SystemLabels] ADD CONSTRAINT [DF_SystemLabels_CreatedAt] DEFAULT (getdate()) FOR [CreatedAt]
GO
NOTE This table can't have foreign key to SystemLanguages due to circular dependency
Table LocalizationLevel0
CREATE TABLE [ref].[LocalizationLevel0](
[Id] [int] NOT NULL,
[IdSystemLabel] [int] NOT NULL,
[IsoCode] [nchar](2) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
[UpdatedAt] [datetime] NULL,
[Enabled] [bit] NULL,
CONSTRAINT [PK_LocalizationLevel0] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [ref].[LocalizationLevel0] ADD CONSTRAINT [DF_LocalizationLevel0_CreatedAt] DEFAULT (getdate()) FOR [CreatedAt]
GO
ALTER TABLE [ref].[LocalizationLevel0] ADD CONSTRAINT [DF_LocalizationLevel0_Enabled] DEFAULT ((0)) FOR [Enabled]
GO
I'm trying to explain my logic :
One localizationlevel0 item can have a translation in multiple system languages :
Example for FRANCE country
1 4 'FR' '2015-04-17 00:00:00:000' NULL 1
-- System Languages
1 1 'FR' 1
2 2 'EN' 1
3 3 'DE' 1
-- Corresponding wordings
1 1 'Français' NULL '2015-04-17 00:00:00:000' NULL 'SystemLanguages'
1 2 'French' NULL '2015-04-17 00:00:00:000' NULL 'SystemLanguages'
1 2 'Französisch' NULL '2015-04-17 00:00:00:000' NULL 'SystemLanguages'
...
4 1 'France' NULL '2015-04-17 00:00:00:000' NULL 'LocalizationLevel0'
4 2 'France' NULL '2015-04-17 00:00:00:000' NULL 'LocalizationLevel0'
4 3 'Frankreich' NULL '2015-04-17 00:00:00:000' NULL 'LocalizationLevel0'
You have to always reference the whole primary key.
So, if the first table has a composite primary key (Id, IdLanguage), the second table has to have also a composite foreign key (SystemLabels.Id, SystemLabels.Language) and not just (SystemLabels.Id).
I would check out the question IX in this article:
https://www.simple-talk.com/sql/t-sql-programming/questions-about-primary-and-foreign-keys-you-were-too-shy-to-ask/

get rows and rows from one table SQL server

i have comments table in sql server structured as
CREATE TABLE [dbo].[LS_Commentes](
[CommentId] [int] IDENTITY(1,1) NOT NULL,
[OwnerId] [uniqueidentifier] NULL,
[OwnerName] [nvarchar](50) NULL,
[Email] [nvarchar](250) NULL,
[Date] [nvarchar](15) NULL,
[ParentId] [int] NULL,
[CommentText] [nvarchar](400) NULL,
[ItemId] [int] NULL,
[upVotes] [int] NULL,
[downVotes] [int] NULL,
[isApproved] [bit] NULL,
CONSTRAINT [PK_LS_MsgCommentes] PRIMARY KEY CLUSTERED
(
[CommentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
and i have sample data like this:
CommentId OwnerId OwnerName Email Date ParentId CommentText ItemId upVotes downVotes isApproved
1 NULL Test Commneter NULL 1/4/2013 NULL test 9 0 0 NULL
2 NULL Test Commneter NULL 1/4/2013 1 test NULL 0 0 NULL
3 NULL Test Commneter NULL 1/4/2013 1 test NULL 0 0 NULL
i want to write one query can get me all rows have itemid =9 and rows have parentid= comment id that selected (because itemid = 9)
look here i can solve it by adding item id 9 to the sub comments too but i just want to know if that could be solved without adding item id to comments and sub comments
I think the following query does what you want:
select *
from ls_comments c
where c.itemID = 9 or
c.parentID in (select c2.commentId from ls_comments c2 where c2.itemId = 9)
Would a recursive Common Table Expression give you the results you're after?
;with cte as
(
--Anchor
select
commentid,
ParentId
from
LS_Commentes
where
ItemId = 9
union all
--Recursive member
select
c.commentId,
c.ParentId
from
LS_Commentes c join cte on c.ParentId = cte.CommentId
)
select * from cte
If you want to include more columns in the results ensure that both parts (the Anchor and recursive member) have identical columns.
Explanation:
The anchor part (the first select) of a recursive query selects all rows where ItemId = 9, the second part uses the existing records in the result to include further records that satisfy it's criters (ParentId = cte.CommentId) this keeps going until nothing more is selected. And then the entire results must be selected at the end (after the CTEs definition)
I think it would be good with an embedded SQL query
SELECT *
FROM `LS_Commentes`
WHERE `ItemId` = '9'
AND `ParentID`= (SELECT `CommentID` FROM `LS_Commentes` WHERE `ItemId` = 9);

In a SQL Query, How do I do a join only on specific conditions?

I have the following SQL Query:
select Subjects.S_ID as ID,
Subjects.S_ParentID as ParentID,
Subjects.S_Name as Name,
Subjects.S_Order as [Order],
subjects.Sbj_IsVisible
from Subjects
left join KPI_SubjectDetails k on Subjects.S_ID = k.S_ID
where
subjects.Sbj_CourseID = 7594
and subjects.Sbj_Type=2
and subjects.Sbj_IsVisible=1
order by subjects.S_Level,
k.SD_Order
Each Subject has a s_ParentID. The most top subjects have a s_ParnetID of 0.
I want to add a SQL Join, which will do the following:
If a parent Subject is set to Sbj_IsVisible = 0 (any subject can be a parent), then the SQL should not output it or any of its children. However, if s_ParentID is set to 0, I don't want to do the Sbj_IsVisible check as this is the top most subject.
Here's what I got:
select Subjects.S_ID as ID,
Subjects.S_ParentID as ParentID,
Subjects.S_Name as Name,
Subjects.S_Order as [Order],
subjects.Sbj_IsVisible
from Subjects
join Subjects_tbl st on Subjects.S_ParentID = st.S_ID and subjects.S_ParentID <> 0
left join KPI_SubjectDetails k on Subjects.S_ID = k.S_ID
where
subjects.Sbj_CourseID = 7594
and subjects.Sbj_Type=2
and subjects.Sbj_IsVisible=1
and st.Sbj_IsVisible = 1
order by subjects.S_Level,
k.SD_Order
This partly works. When a parent subject is set to sbj_Isvisible 0, it does not return its children.
However, if the top most subject is set to sbj_IsVisible 1, the top most subject does not output, but its children do.
BTW, This is one a SQL Server 2008.
//edit
adding some example data.
This is the output of the original query:
ID ParentID Name Order Sbj_IsVisible
9017 0 'Boot Camp' 18 1
9033 9017 1 4 1
9049 9017 test 1 8 1
9050 9049 test 2 1 1
and this is the output of my query:
ID ParentID Name Order Sbj_IsVisible
9033 9017 1 4 1
9049 9017 test 1 8 1
9050 9049 test 2 1 1
here's the create table output:
USE [Fox8]
GO
/****** Object: Table [dbo].[Subjects_tbl] Script Date: 02/22/2012 16:25:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Subjects_tbl](
[S_ID] [int] IDENTITY(1,1) NOT NULL,
[S_TopID] [int] NULL,
[S_ParentID] [int] NULL,
[S_Name] [nvarchar](255) NULL,
[S_Order] [int] NULL,
[S_ItemCount] [int] NOT NULL,
[S_Level] [int] NULL,
[S_IsInherited] [int] NOT NULL,
[S_SortType] [nvarchar](50) NULL,
[S_SortOrder] [nvarchar](50) NULL,
[OriginalSbj_CourseID] [int] NULL,
[Sbj_CourseID] [int] NOT NULL,
[Sbj_IsVisible] [int] NULL,
[Sbj_SkinType] [int] NULL,
[CopyOf_SubjectID] [int] NULL,
[Sbj_GUID] [uniqueidentifier] NULL,
[Sbj_type] [int] NULL,
[s_OriginalSubjectID] [int] NULL,
[OriginalEvalTree_SbjId] [int] NULL,
[S_IsDeleted] [smallint] NOT NULL,
[S_DateDeleted] [datetime] NULL,
[S_IsPrimary] [bit] NULL,
CONSTRAINT [PK_Subjects] PRIMARY KEY CLUSTERED
(
[S_ID] ASC,
[S_ItemCount] ASC,
[Sbj_CourseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UX_Subjects_S_ID_Sbj_CourseID] UNIQUE NONCLUSTERED
(
[S_ID] ASC,
[Sbj_CourseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
EXEC sys.sp_addextendedproperty #name=N'MS_Description', #value=N'bitwise field 1 for regular subject 2 for weighted Subject 4 for X of Y Subject' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'TABLE',#level1name=N'Subjects_tbl', #level2type=N'COLUMN',#level2name=N'Sbj_type'
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD CONSTRAINT [DF_Subjects_S_ItemCount] DEFAULT ((0)) FOR [S_ItemCount]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD CONSTRAINT [DF_Subjects_S_IsInherited] DEFAULT ((1)) FOR [S_IsInherited]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD CONSTRAINT [DF_Subjects_Sbj_CourseID] DEFAULT ((-1)) FOR [Sbj_CourseID]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD DEFAULT ((0)) FOR [Sbj_SkinType]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD CONSTRAINT [DF_Subjects_Sbj_IsEvaluation] DEFAULT ((1)) FOR [Sbj_type]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD DEFAULT ((0)) FOR [S_IsDeleted]
GO
ALTER TABLE [dbo].[Subjects_tbl] ADD DEFAULT ((0)) FOR [S_IsPrimary]
GO
Your question is a little confusing to me but let me suggest using an OR clause, as in:
SELECT s.S_ID AS ID, s.S_ParentID AS ParentID, s.S_Name AS Name,
s.S_Order AS [Order], s.Sbj_IsVisible
FROM Subjects s
LEFT JOIN Subjects_tbl st ON s.S_ParentID = st.S_ID
LEFT JOIN KPI_SubjectDetails k ON s.S_ID = k.S_ID
WHERE s.Sbj_CourseID = 7594
AND s.Sbj_Type=2
AND s.Sbj_IsVisible = 1
AND (st.Sbj_IsVisible = 0 OR s.S_ParentID = 0)
ORDER BY s.S_Level, k.SD_Order
Essentially, select information from the subjects table if either it's corresponding parent is not visible or it does not have a corresponding parent (along with whatever your other conditions mean).
Hope that helps!