SQL querying/searching records from inner join's columns - sql-server

The query:
SELECT
(STUFF((SELECT ',' + CONVERT(VARCHAR(50),mode.model_name)
FROM InventoryMake SUB INNER JOIN Model mode ON SUB.model_ID = mode.model_ID
WHERE SUB.inv_ID = CAT.inv_ID FOR XML PATH('')), 1, 1, '' )) [Models],CAT.inv_ID
FROM Inventory CAT
Results from the query are as below:
Models inv_ID
Pulsar,Hunk 14
Splender,Hunk 15
Chaly (CF50),Hunk,CBZ,Splender 16
Pulsar,Hunk 17
Pulsar,Hunk,CBZ 18
As you can see from the query above InventoryMake table has the foreign keys from the tables Inventory and Model. Shown below are illustrations of those tables.
Inventory table
inv_ID inv_name
14 abc
15 bcx
16 glx
17 lco
18 btx
InventoryMake table
inm_id inv_ID model_ID
1 2 15
7 3 15
8 5 16
9 3 16
10 4 16
11 2 16
12 1 14
13 3 14
14 1 17
15 3 17
Model Table
model_ID model_name
1 Pulsar
2 Splender
3 Hunk
4 CBZ
5 Chaly (CF50)
What I need to do is to find the records for the users input that matches either inv_ID from the Inventory table or the model_name from the Model table. For that I have edited the query as below.
SELECT
(STUFF((SELECT ',' + CONVERT(VARCHAR(50),mode.model_name)
FROM InventoryMake SUB INNER JOIN Model mode ON SUB.model_ID = mode.model_ID
WHERE SUB.inv_ID = CAT.inv_ID FOR XML PATH('')), 1, 1, '' )) [Models],CAT.inv_ID
FROM Inventory CAT WHERE CAT.inv_ID LIKE '%#term%'
From the above query its possible to find the records that matches the term in inv_ID. But I need to find the records that matches either Inventory.inv_ID or Model.model_name. How do you suggest I can achieve this?
Thanks in advance.
PS: I'm using MSSQL

I don't knwo why your query has a function called STUFF neither what is FOR XML PATH('').
I'm also not sure about the meaning of '%#term%', or if it works as you seem to expect (it would not work in MySQL.
So, ignoring your query and looking at your formulated question, my answer is:
SELECT SUB.inm_id, SUB.inv_ID, SUB.model_ID
FROM InventoryMake SUB
INNER JOIN Inventory CAT ON (SUB.inv_ID = CAT.inv_ID)
INNER JOIN Model ON (SUB.model_ID = Model.model_ID)
WHERE CAT.inv_ID = #term
OR Model.model_name LIKE '%#term%'
Note that it does not make much sense to use LIKE against CAT.inv_ID. Maybe what you want is actually to match user's input against inv_name?

Related

SQL update table loop

I have this following query that gets me a small result set
SELECT
LOC, PLAN, FiscalYear, FiscalPeriod, SALES
FROM
#CurrentPrd PrdAg
WHERE
NOT EXISTS (SELECT AGE.ECPLAN
FROM ECPG_BAK AGE
WHERE PrdAg.LOC = AGE.STORE
AND PrdAg.PLAN = AGE.PLAN
AND PrdAg.FiscalYear = AGE.FiscalYear
AND PrdAg.FiscalPeriod = AGE.FiscalPeriod)
The result set looks like this:
LOC PLAN FiscalYear FiscalPeriod SALES
---------------------------------------------------
5 6 2031 5 -0.206232
12 6 2031 5 5.243052
12 8 2020 4 1.699716
12 8 2020 5 1.699716
14 6 2031 5 0.299972
19 6 2031 5 1.549812
19 8 2020 5 20.114116
33 6 2031 5 2.159767
33 8 2020 5 23.796883
34 6 2031 5 1.142360
34 8 2020 5 9.348583
................................................
Then I have this other query that gets me a number that I need to add to the SALES column. For example, the query below, I used fixed loc and plan to come up with a number:
select
(select SALES
from #TOT
where loc = 12 and PLAN = 6) - (select sum(sales)
from #CurrentPrd
where store = 12 and PLAN = 6) as Comp
Let's assume this query above gets me 10, then I need to add it to line 2 of the result set above, making it
LOC PLAN FiscalYear FiscalPeriod SALES
----------------------------------------------
12 6 2031 5 15.243052
My goal is to make it somewhat dynamic and do the whole process in a simple way, so for each LOC and PLAN combination, I would plug those values into the second select to retrieve the correct number to add to SALES, then update #CurrentPrd. Writing the new number to a new temp table is also an option.
I hope I was able to explain what I'm trying to do. Any help would be appreciated.
Thanks.
Without any actual test data, it's hard to say for sure but I think something like the following should work for you...
SELECT
PrdAg.LOC,
PrdAg.[PLAN],
PrdAg.FiscalYear,
PrdAg.FiscalPeriod,
SALES = PrdAg.SALES + (tx.SALES - cpx.SALES)
FROM
#CurrentPrd PrdAg
CROSS APPLY (SELECT TOP 1 T.SALES FROM #TOT T WHERE PrdAg.LOC = T.LOC AND PrdAg.[PLAN] = t.[PLAN]) tx
CROSS APPLY (SELECT SALES = SUM(CP.SALES) FROM #CurrentPrd CP WHERE PrdAg.LOC = CP.LOC AND PrdAg.[PLAN] = CP.[PLAN]) cpx
WHERE
NOT EXISTS (
SELECT 1
FROM
ECPG_BAK AGE
WHERE
PrdAg.LOC = AGE.STORE
AND PrdAg.[PLAN] = AGE.[PLAN]
AND PrdAg.FiscalYear = AGE.FiscalYear
AND PrdAg.FiscalPeriod = AGE.FiscalPeriod
);

How to delete not duplicated rows of 2 tables that only 2 columns of them compare for duplication in SQL Server

I want a stored procedure to create a temptable based on 2 columns of table_A, and then check if there are rows in table_B (with 5 columns) that have these 2 columns like the way they are in table_A. Don't do anything to them a delete rows that are not duplicate.
Something like this:
Create Procedure DeleteExtra
as
Create Table #TempTotalHoney
(
HarvestDate Date,
HoneyType VarChar(50)
)
INSERT INTO #TempTotalHoney
Select HarvestDate, HoneyType
From tHoneyHarvest
Group BY HarvestDate, HoneyType
//until here temptable created as I want, but I don't know how to check
//not duplicated rows, I tried this But it is wrong...
Delete From tHoneyWeight
Where HarvestDate AND HoneyType Not in (select HarvestDate, HoneyType
From #TempTotalHoney)
//must check these tow columns together not separately
If(OBJECT_ID('tempdb..#TempTotalHoney') Is Not Null)
Begin
Drop Table #TempTotalHoney
End
This is the error I get:
Msg 4145, Level 15, State 1, Procedure DeleteExtra, Line 17
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.
Update:
this is #TempTotalHoney that created from table_A
HarvestDate HoneyType
---------------------------------------------------
2017-01-10 Pure
2017-01-10 Semi-Pure
2017-02-03 Pure
2017-02-04 artificial
and
table_B:
RecID HarvestDate HoneyType TotalCombs TotalWeight
----------------------------------------------------------------
1 2017-01-10 Pure 10 22
3 2017-01-10 Semi-Pure 11 24
4 2017-02-03 Pure 22 50
6 2017-02-04 artificial 25 56
8 2017-01-10 Semi-Art 10 18.5
9 2017-02-05 Pure 11 19
I want the RecID 8 and 9 that combination of HarvestDate And HoneyType of them not exists in #TempTotalHoney be deleted.
You can try using below query
DELETE table_B
FROM table_B B
LEFT JOIN #TempTotalHoney A
ON B.HarvestDate = A.HarvestDate
AND B.HoneyType = A.HoneyType
WHERE A.HoneyType is Null;
Hope this would help you out.

How can an SQL query return data from these tables?

I have TrsViewPay view with this sample data:
id DocTypeRef TrsDocPayItemref
---------------------------------
1 10 16
2 20 17
3 30 18
4 40 1
First I don't want to show record with DocTypeRef 40.
Then I don't want to show the records where the id is equal with that record's TrsDocPayItemref.
So I want to show this result (without record 1 and 4)
id DocTypeRef TrsDocPayItemref
---------------------------------
2 20 17
3 30 18
Ravi's answer is close, but I think this one will be better:
SELECT Id, DocTypeRef, TrsDocPayItemref
FROM TrsViewPay
WHERE DocTypeRef <> 40
AND Id <> (SELECT TrsDocPayItemref FROM TrsViewPay WHERE DocTypeRef = 40)
You can go for inner queries or sub queries. You can first Select the value of
DocTypeRef and then compare it with id. use first point as inner query. After that you can retrieve data using the result of first query.
You can try this:
SELECT *
FROM TrsViewPay
WHERE DocTypeRef!=40
AND NOT TrsDocPayItemref IN (SELECT id FROM TrsViewPay )

Select multi value from another table and put in one string split by -

I have 2 tables in MS SQL Server.
Table 1
ID Name
-------------
10 Series
11 Movie
12 Music
13 Other
Table 2
ID IDCatg Value
---------------------------
1 10 Hannibal
2 10 Blacklist
3 10 POI
4 11 Hitman
5 11 SAW
6 11 Spider man
7 12 taylor swift
8 12 britney spears
I want to select by IDCatg in Table 2 and create a new column in Table 1 like this:
IDCatg Name Value
--------------------------------------------
10 Series Hannibal-Blacklist-POI
11 Movie Hitman-SAW-Spider man
12 Music taylor swift-britney spears
How can I do this by view?
You can do it using STUFF:
SELECT T21.IDCatg, T1.Name,
[Value] = STUFF((
SELECT '-' + T22.[Value]
FROM Table2 T22
WHERE T21.IDCatg = T22.IDCatg
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Table2 T21 JOIN
Table1 T1 ON T1.ID=T21.IDCatg
GROUP BY T21.IDCatg,T1.Name
Result:
IDCatg Name Value
---------------------------------------------
10 Series Hannibal-Blacklist-POI
11 Movie Hitman-SAW-Spider man
12 Music taylor swift-britney spears
Sample result in SQL Fiddle
EDIT:
When the type of Value is int, you can cast it to varchar:
[Value] = STUFF((
SELECT '-' + CAST(T22.[Value] AS Varchar(MAX))

i have 4 table in sql and i want the data or all the table where one unique key is matched in four of them

I have a table ratings, bookmark, checkin, food in food table there is a unique key sno and this sno key is used in remaining three tables.
food table
sno name totalrating totalcheckin
1 nitesh 52 45
2 abhishek 4 9
3 divye 42 30
ratings table
sno datakey rated name
1 3 3.0 divye
1 6 4.0 shashank
bookmark table
sno datakey name
1 3 divye
1 6 shashank
Checkin table
sno datakey name
1 2 abhishek
1 6 shashank
I need data where datakey is 3 if not present show null values and data key column not repeated
like
0 1 2 3 4 5 6 7 8 9 10
sno name totalrating totalcheckin sno rated name sno name sno name
3 divye 42 30 1 3.0 divye 1 divye null null
your query should look like this:
SELECT f.sno, f.name, f.totalrating, f.totalcheckin,
r.sno, r.rated, r.name,
b.sno, b.name,
c.sno, c.name
FROM food AS f
LEFT JOIN ratings AS r
ON f.sno = r.datakey
LEFT JOIN bookmark AS b
ON f.sno = b.datakey
LEFT JOIN checkin AS c
ON f.sno = c.datakey
WHERE f.sno = 3
Here is SQL Fiddle to see how it's work.
Also I agree with the guys in the comment which are told you to read something about JOIN syntax. It's pretty and you can start here, or more specific for your problem is LEFT JOIN, that is the begin and good place to start. Also you can see that I use aliases in my query about that read here.
GL!
P.S. (edit) and if you have any question fill free to ask... Also I notice that you have name column in every table, if I understand relation between your table it's not necessary. You should store name only in first table (food) and with simple JOIN from there you can pull that data whenever you need it!

Resources