How to write sql clause where column not equal and any id associated - sql

I want to setup a simple query that will filter out any row that contains "A" in the ItemID, but my issue is I also do NOT want to display any journal ID from a different row since it matched "A". I tried googling the solution, but I am sure I am not using the right keywords to find it. I am using microsoft sql 2008, but I am not a database admin so I am not to familiar. I tried using distinct, and I also tried group by, but in this situation it does not work.
This is a simplified version of the table that I am working with:
JournalID ItemID PrimaryKEY
1 A 1
1 B 2
2 A 3
2 C 4
3 B 5
4 D 6
And here is how I would like to make it look:
JournalID ItemID PrimaryKEY
3 B 5
4 D 6

This will exclude any rows where the ItemID is 'A' and also any rows that have the same JournalID as a row where a ItemID was 'A'.
SELECT JournalID, ItemID, PrimaryKEY
FROM TABLE
WHERE JournalID NOT IN (Select JournalID FROM TABLE WHERE ItemID = 'A')

Try this:
SELECT *
FROM table_name
WHERE JournalID
NOT IN (SELECT JournalID
FROM table_name
WHERE ItemID = 'A')

Related

How add more rows when find string in column Oracle

Would it be possible to add more rows base on Keyword string in SQL ?
table A
PID PromotionName
1 OUT_EC_D10_V500K_FamilyCare_PROCO
2 OUT_EC_D5_V50K_Lunchbox_PROCO
3 OUT_EC_D5_V50K_PROCO
table B
promotion_code itm_name quantity
Lunchbox Item name 1 1
FamilyCare Item name 2 1
FamilyCare Item name 3 1
BUY1FREE6 Item name 4 1
HiSummer Item name 5 1
FamilyCare Item name 6 1
Example:
SELECT * FROM A where pid = '1';
Output of the SQL should be -
PID PromotionName Itm_name quantity
1 OUT_EC_D10_V500K_FamilyCare_PROCO
2 FamilyCare Item name 2 1
3 FamilyCare Item name 3 1
4 FamilyCare Item name 6 1
How to find string with keyword 'FamilyCare' in PromotionName of table A base on promotion_code of table B? If it exist it will add more rows in output
Any help with the SQL?
Here is how you can achieve this:
SELECT PID,PromotionName, '' as Itm_name, NULL as quantity
FROM A
WHERE pid = '1'
UNION
SELECT PID, PROMOTION_NAME, Itm_name, quantity
FROM
(SELECT * FROM A inner join B on a.promotionName LIKE '%'||b.promotion_name||'%')
WHERE pid='1'
You have to update your pid in both the places (before and after UNION).
Notice that tables were joined using LIKE operator with % before and after the word. Hence this joins if a part of a string is present in another column.
db<>fiddle link here
An option would be starting to construct a subquery factoring along with joining tables through a.promotionName LIKE '%'||b.promotion_code||'%' condition while filtering by b.promotion_code = 'FamilyCare', then add another query to combine the result sets by UNION ALL, and then enumerate with an id column by ROW_NUMBER() analytic function such as
WITH ab AS
(
SELECT a.*, b.*
FROM a
JOIN b
ON a.promotionName LIKE '%'||b.promotion_code||'%'
WHERE b.promotion_code = 'FamilyCare'
), ab2 AS
(
SELECT promotion_code, itm_name, quantity
FROM ab
UNION ALL
SELECT DISTINCT promotionName, NULL, NULL
FROM ab
)
SELECT ROW_NUMBER() OVER (ORDER BY itm_name NULLS FIRST) AS pid,
a.*
FROM ab2 a
if there's mismatch for the topmost query, then no row will be returned. eg. that query will check for the existence for the literal you provide
Demo

Need to find out if all columns in a SQL Server table have the same value

I have the task to find out if all columns in a SQL Server table have exact the same value. The table content is created by a stored procedure and can vary in the number of columns. The first column is an ID, the second and the following columns must be compared if the all columns have exact the same value.
At the moment I do not have a clue how to achieve this.
The best solution would be to display only the rows, which have different values in one or multiple columns except the first column with ID.
Thank you so much for your help!!
--> Edit: The table looks this:
ID Instance1 Instance2 Instance3 Instance4 Instance5
=====================================================
A 1 1 1 1 1
B 1 1 0 1 1
C 55 55 55 55 55
D Driver Driver Driver Co-driver Driver
E 90 0 90 0 50
F On On On On On
The result should look like this, only the rows with one or multiple different column values should be display.
ID Instance1 Instance2 Instance3 Instance4 Instance5
=====================================================
B 1 1 0 1 1
D Driver Driver Driver Co-driver Driver
E 90 0 90 0 50
My table has more than 1000 rows and 40 columns
you can achieve this by using row_number()
Try the following code
With c as(
Select id
,field_1
,field_2
,field_3
,field_n
,row_number() over(partition by field_1,field_2,field_3,field_n order by id asc) as rn
From Table
)
Select *
From c
Where rn = 1
row_number with partition is going to show you if the field is repeated by assigning a number to a row based on field_1,field_2,field_3,field_n, for example if you have 2 rows with same field values the inner query is going to show you
rn field_1 field_2 field_3 field_n id
1 x y z a 5
2 x y z a 9
After that on the outer part of the query pick rn = 1 and you are going to obtain a query without repetitions based on fields.
Also if you want to delete repeated numbers from your table you can apply
With c as(
Select id
,field_1
,field_2
,field_3
,field_n
,row_number() over(partition by field_1,field_2,field_3,field_n order by id asc) as rn
From Table
)
delete
From c
Where rn > 1
The best solution would be to display only the rows, which have different values in one or multiple columns except the first column with ID.
You may be looking for a the following simple query, whose WHERE clause filters out rows where all fields have the same value (I assumed 5 fields - id not included).
SELECT *
FROM mytable t
WHERE NOT (
field1 = field2
AND field1 = field3
AND field1 = field4
AND field1 = field5
);

Checking for (and Deleting) Complex Object Duplicates in SQL Server

So I need to duplicate check a complex object, and then cascade delete dupes from all associated tables and I'm wondering if I can do it efficiently in SQL Server, or if I should go about it in my code. Structurally I have the following tables.
Claim
ClaimCaseSubTypes (mapping table for many to many relationship)
ClaimDiagnosticCodes (ditto)
ClaimTreatmentCodes (ditto)
Basically a Claim is only a duplicate if it is matching on 8 fields in itself AND has the same relationships in all the mapping tables.
For Example, the following records would be indicated as duplicates
Claim
Id CreateDate Other Fields
1 1/1/2015 matched
2 6/1/2015 matched
ClaimCaseSubTypes
ClaimId SubTypeId
1 34
1 64
2 34
2 64
ClaimDiagnosticCodes
ClaimId DiagnosticCodeId
1 1
2 1
ClaimTreatmentCodes
ClaimId TreatmentCodeId
1 5
1 6
2 6
2 5
And in this case I would want to keep 1 and delete 2 from the Claim table as well as any rows in the mapping tables with ClaimId of 2
This is the kind of problem that window functions are for:
;WITH cte AS (
SELECT c.ID,
ROW_NUMBER() OVER (PARTITION BY field1, field2, field3, ... ORDER BY c.CreateDate) As ClaimOrder
FROM Claim c
INNER JOIN other tables...
)
UPDATE Claim
SET IsDuplicate = IIF(cte.ClaimOrder = 1, 0, 1)
FROM Claim c
INNER JOIN cte ON c.ID = cte.ID
The fields that you include in the PARTITION BY indicates what fields need to be identical for two claims to be considered matched. The ORDER BY tell SQL Server assign the earliest claim the order of 1. Everything that doesn't have the order of 1 is a duplicate of something else.

Access SQL query to mailmerge

How can I transform this table from this
id name
1 sam
2 nick
3 ali
4 farah
5 josef
6 fadi
to
id1 name1 id2 name2 id3 name3 id4 name4
1 sam 2 nick 3 ali 4 farah
5 josef 6 fadi
the reason i need this is i have a database and i need to do a mail merge using word and I want to print every 4 rows on one page, MS word can only print one row per page, so using an SQL query I want one row to represent 4 rows
thanks in advance
Ali
You don't need to create a query for this in Access. Word has a merge field called <<Next Record>> which forces moving to the next record. If you look at how label documents are created using the Mail Merge Wizard, you'll see that's how it's done.
Updated - Doing this in SQL
The columns in simple SELECT statements are derived from the columns from the underlying table/query (or from expressions). If you want to define columns based on the data, you need to use a crosstab query.
First create a query with a running count for each person (say your table is called People), and calculate the row and column position from the running count:
SELECT People.id, Count(*)-1 AS RunningCount, int(RunningCount/4) AS RowNumber, RunningCount Mod 4 AS ColumnNumber
FROM People
LEFT JOIN People AS People_1 ON People.id >= People_1.id
GROUP BY People.id;
(You won't be able to view this in the Query Designer, because the JOIN isn't comparing with = but with >=.)
This query returns the following results:
id Rank RowNumber ColumnNumber
1 0 0 0
2 1 0 1
3 2 0 2
4 3 0 3
5 4 1 0
6 5 1 1
Assuming this query is saved as Positions, the following query will return the results:
TRANSFORM First(Item) AS FirstOfItem
SELECT RowNumber
FROM (
SELECT ID AS Item, RowNumber, "id" &( ColumnNumber + 1) AS ColumnHeading
FROM Positions
UNION ALL SELECT Name, RowNumber, "name" & (ColumnNumber +1)
FROM Positions
INNER JOIN People ON Positions.id = People.id
) AS AllValues
GROUP BY AllValues.RowNumber
PIVOT AllValues.ColumnHeading In ("id1","name1","id2","name2","id3","name3","id4","name4");
The UNION is there so each record in the People table will have two columns - one with the id, and one with the name.
The PIVOT clause forces the columns to the specified order, and not in alphabetical order (e.g. id1, id2 ... name1, name2...)

SQL query for dynamic insert row

I am having data like:
ItemCode Attribute PositionID
ITEM-000032 CHESTSIZE 1
ITEM-000032 JACKETLEN 2
ITEM-000042 CHESTSIZE 1
ITEM-000042 JACKETLEN 2
**ITEM-000049 SLACKWAIST 1**
ITEM-000071 CHESTSIZE 1
ITEM-000071 JACKETLEN 2
ITEM-000074 CHESTSIZE 1
ITEM-000074 JACKETLEN 2
In above data except ITEM-000049 others are having perfect combination. so i want to create a new row for ITEM-000049
As
ITEM-000049 -- 2
to make it perfect.
Kind regards,
Om
Sounds like for each ItemCode, you are expecting 2 records, for 2 different Attributes.
So something like this is what I think you're after. Just run the SELECT part of it first without the INSERT to check it is indeed what you're after.
INSERT YourTable (ItemCode, Attribute, PositionID)
SELECT t.ItemCode, 'SECOND ATTRIBUTE', 2
FROM
(
SELECT ItemCode
FROM YourTable
GROUP BY ItemCode
HAVING COUNT(*) = 1
) t