How can I select none duplicate rows with inner join? - sql

My MS SQL Server stored procedure is:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_close]
#DATE NVARCHAR(8)
AS
BEGIN
SELECT appointment_datas.appointment_date
,appointment_datas.appointment_no
,costumer_datas.costumer_name
,appointment_datas.appointment_type
,personel_datas.personel_ADI
FROM [LONI].[dbo].appointment_datas
INNER JOIN [LONI].[dbo].costumer_datas ON appointment_datas.appointment_costumer = costumer_datas.costumer_id
INNER JOIN [LONI].[dbo].personel_datas ON appointment_datas.appointment_personel = personel_datas.personel_id
INNER JOIN [GUONU].[dbo].dayend ON appointment_datas.appointment_no <> dayend.appointment_no COLLATE Turkish_CI_AS
WHERE CONVERT(nvarchar(8),appointment_datas.appointment_date,112) = #DATE
END
With this code, I select duplicate rows from the same records. Actually I want to select fields from [LONI].[dbo].appointment_datas but if appointment_no
is not in [GUONU].[dbo].dayend

SELECT DISTINCT removes duplicates in your output.
But your SQL looks wrong. Are you sure you mean to write:
TABLE1.FIELD1 <> TABLE1.FIELD1
This always evaulates to false. I think you may have an error in your SQL, and that might be why you are getting duplicate values. You should rarely use <> in a join clause, and you shouldn't have the same field on both sides.
Maybe you intended:
ON [DB1].[dbo].TABLE1.FIELD1 <> [DB2].[dbo].TABLE1.FIELD1
but this will generate a Cartesian product of all the rows that don't match. I doubt this is what you really mean. Perhaps you want this:
ON [DB1].[dbo].TABLE1.ID = [DB2].[dbo].TABLE1.ID
WHERE[DB1].[dbo].TABLE1.FIELD1 <> [DB2].[dbo].TABLE1.FIELD1
This matches the rows from each database that have the same ID, but differ in a certain column. Notice that the <> is not in the JOIN clause.
--- UPDATE ---
Perhaps you mean to select the results from the two different databases and then union them?
SELECT appointment_datas.appointment_date
,appointment_datas.appointment_no
,costumer_datas.costumer_name
,appointment_datas.appointment_type
,personel_datas.personel_ADI
FROM [LONI].[dbo].appointment_datas
INNER JOIN [LONI].[dbo].costumer_datas ON appointment_datas.appointment_costumer = costumer_datas.costumer_id
INNER JOIN [LONI].[dbo].personel_datas ON appointment_datas.appointment_personel = personel_datas.personel_id
WHERE CONVERT(nvarchar(8),appointment_datas.appointment_date,112)
UNION
SELECT appointment_datas.appointment_date
,appointment_datas.appointment_no
,costumer_datas.costumer_name
,appointment_datas.appointment_type
,personel_datas.personel_ADI
FROM [GUONU].[dbo].appointment_datas
INNER JOIN [GUONU].[dbo].costumer_datas ON appointment_datas.appointment_costumer = costumer_datas.costumer_id
INNER JOIN [GUONU].[dbo].personel_datas ON appointment_datas.appointment_personel = personel_datas.personel_id
WHERE CONVERT(nvarchar(8),appointment_datas.appointment_date,112)
--- SOLUTION ---
Use NOT EXISTS in WHERE clause. Read comments to see why.

The line
INNER JOIN [DB2].[dbo].TABLE1 ON TABLE1.FIELD1 <> TABLE1.FIELD1
makes no sense, you want to rephrase that...

If I understand your question correctly (after your edit)
but if appointment_no is not in
[GUONU].[dbo].dayend
, you actually want a NOT EXISTS subquery:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_close]
#DATE NVARCHAR(8)
AS
BEGIN
SELECT appointment_datas.appointment_date
,appointment_datas.appointment_no
,costumer_datas.costumer_name
,appointment_datas.appointment_type
,personel_datas.personel_ADI
FROM [LONI].[dbo].appointment_datas
INNER JOIN [LONI].[dbo].costumer_datas ON appointment_datas.appointment_costumer = costumer_datas.costumer_id
INNER JOIN [LONI].[dbo].personel_datas ON appointment_datas.appointment_personel = personel_datas.personel_id
WHERE CONVERT(nvarchar(8),appointment_datas.appointment_date,112) = #DATE
AND NOT EXISTS (SELECT 'X' FROM [GUONU].[dbo].dayend WHERE dayend.appointment_no = appointment_datas.appointment_no)
END

SELECT DISTINCT TABLE1.FIELD1
,TABLE2.FIELD1
,TABLE1.FIELD3
,TABLE3.FIELD1
FROM ...
NB in some variants you will have to bracket the field list ie
SELECT DISTINCT (TABLE1.FIELD1
,TABLE2.FIELD1
,TABLE1.FIELD3
,TABLE3.FIELD1 ) FROM ...

Related

How do I display the count value of the results from one column in a new column?

This stored procedure returns two values but it repeats multiple times.
I am trying to get the count value of PLTGRN so that it shows up in a new column like in this image:
My code:
ALTER PROCEDURE[dbo].[GreenTire_Fits_In_Press]
#Press varchar(10)
AS
BEGIN
SELECT FAC,PLTGRN
FROM [TireTrack].[dbo].[cos_work] cosw WITH (nolock)
INNER JOIN [DataWarehouse].[dbo].[v_Curing_Tooling] CURE WITH (Nolock) ON Cure.MLDNBR = Cosw.MOLD
WHERE Cosw.FAC = #Press
END
I tried adding COUNT(PLTGRN) in the select statement to the code above but that throws this error :
you need to use GROUP BY :
ALTER PROCEDURE[dbo].[GreenTire_Fits_In_Press]
#Press varchar(10)
AS
BEGIN
Select PLTGRN , COUNT(*) QTY
FROM [TireTrack].[dbo].[cos_work] cosw with (nolock)
Inner Join [DataWarehouse].[dbo].[v_Curing_Tooling] CURE with (Nolock)
On Cure.MLDNBR=Cosw.MOLD
Where Cosw.FAC=#Press
GROUP BY PLTGRN
End
SUM is used with a GROUP BY clause. The aggregate functions summarize the table data. Once the rows are divided into groups, the aggregate functions are applied in order to return just one value per group. It is better to identify each summary row by including the GROUP BY clause in the query result.
ALTER PROCEDURE[dbo].[GreenTire_Fits_In_Press]
#Press varchar(10)
AS
BEGIN
SELECT FAC,PLTGRN, COUNT(PLTGRN)
FROM [TireTrack].[dbo].[cos_work] cosw WITH (nolock)
INNER JOIN [DataWarehouse].[dbo].[v_Curing_Tooling] CURE WITH (Nolock) ON Cure.MLDNBR = Cosw.MOLD
WHERE Cosw.FAC = #Press
GROUP BY FAC, PLTGRN
END
-- you are missing group by and the part of the query to get count
ALTER PROCEDURE[dbo].[GreenTire_Fits_In_Press]
#Press varchar(10)
AS
BEGIN
Select FAC,PLTGRN, count(*)
FROM [TireTrack].[dbo].[cos_work] cosw with (nolock)
Inner Join [DataWarehouse].[dbo].[v_Curing_Tooling] CURE with (Nolock)
On Cure.MLDNBR=Cosw.MOLD
Where Cosw.FAC=#Press
Group By FAC,PLTGRN
End

single-row subquery returns more than one row in Redshift when I try to use CASE in UPDATE

I am trying to use a case statement with sub query in a Update statement but I am facing an Issue like
single-row sub query returns more than
Please find my Query which I tried
update r_gl.ac
set meeting_cost = case currency_code when 'IND'
then amount
else round(tgt.amount)
from r_gl.ac tgt
join
(
select distinct
a.frm_cur,
a.to_cur,
a.exch_rate
from b_gl.currncy_conv_dim a
join r_gl.ac b
on (a.frm_cur = 123 and a.to_cur = b.cur_cd and f_rate = 'ABC')
join b_gl.int_fg
on b.in_s=c.in_s and a.cal_sk = trunc(c.intact_dt_key,-2)
) src
on tgt.cur_cd=src.to_cur
)
end
Please help me to solve this issue
Your current CASE expression is missing its END. That aside, I see even bigger problems with your UPDATE statement. Redshift is based on an old version of Postgres, and hence I expect that it would adhere to the same syntax Postgres would use for an update join:
UPDATE table1 AS t1
SET some_column = t2.some_other_column
FROM table2 AS t2
WHERE t1.id = t2.id
Applying this syntax to your current query along with the fix for the CASE expression leaves us with the following:
update r_gl.ac tgt
set meeting_cost = case when currency_code = 'IND'
then tgt.amount
else round(tgt.amount) end
from
(
select distinct
a.frm_cur,
a.to_cur,
a.exch_rate
from b_gl.currncy_conv_dim a
inner join r_gl.ac b
on (a.frm_cur = 123 and a.to_cur = b.cur_cd and f_rate = 'ABC')
inner join b_gl.int_fg
on b.in_s=c.in_s and a.cal_sk = trunc(c.intact_dt_key,-2)
) src
where tgt.cur_cd = src.to_cur
The table to which you are joining r_gl.ac has no effect on the data being used to update, but rather would only affect the update by targeting certain rows. If this be not your intended logic, then you might have to rethink the entire query.

Ms Access query to SQL Server - DistinctRow

What would the syntax be to convert this MS Access query to run in SQL Server as it doesn't have a DistinctRow keyword
UPDATE DISTINCTROW [MyTable]
INNER JOIN [AnotherTable] ON ([MyTable].J5BINB = [AnotherTable].GKBINB)
AND ([MyTable].J5BHNB = [AnotherTable].GKBHNB)
AND ([MyTable].J5BDCD = [AnotherTable].GKBDCD)
SET [AnotherTable].TessereCorso = [MyTable].[J5F7NR];
DISTINCTROW [MyTable] removes duplicate MyTable entries from the results. Example:
select distinctrow items
items.item_number, items.name
from items
join orders on orders.item_id = items.id;
In spite of the join getting you the same item_number and name multiple times when there is more than one order for it, DISTINCTROW reduces this to one row per item. So the whole join is merely for assuring that you only select items for which exist at least one order. You don't find DISTINCTROW in any other DBMS as far as I know. Probably because it is not needed. When checking for existence, we use EXISTS of course (or IN for that matter).
You are joining MyTable and AnotherTable and expect for some reason to get the same MyTable record multifold for one AnotherTable record, so you use DISTINCTROW to only get it once. Your query would (hopefully) fail if you got two different MyTable records for one AnotherTable record.
What the update does is:
update anothertable
set tesserecorso = (select top 1 j5f7nr from mytable where mytable.j5binb = anothertable.gkbinb and ...)
where exists (select * from mytable where mytable.j5binb = anothertable.gkbinb and ...)
But this uses about the same subquery twice. So we'd want to update from a query instead.
The easiest way to get one result record per <some columns> in a standard SQL query is to aggregate data:
select *
from anothertable a
join
(
select j5binb, j5bhnb, j5bdcd, max(j5f7nr) as j5f7nr
from mytable
group by j5binb, j5bhnb, j5bdcd
) m on m.j5binb = a.gkbinb and m.j5bhnb = a.gkbhnb and m.j5bdcd = a.gkbdcd;
How to write an updateble query is different from one DBMS to another. Here is the final update statement for SQL-Server:
update a
set a.tesserecorso = m.j5f7nr
from anothertable a
join
(
select j5binb, j5bhnb, j5bdcd, max(j5f7nr) as j5f7nr
from mytable
group by j5binb, j5bhnb, j5bdcd
) m on m.j5binb = a.gkbinb and m.j5bhnb = a.gkbhnb and m.j5bdcd = a.gkbdcd;
The DISTINCTROW predicate in MS Access SQL removes duplicates across all fields of a table in join statements and not just the selected fields of query (which DISTINCT in practically all SQL dialects do). So consider selecting all fields in a derived table with DISTINCT predicate:
UPDATE [AnotherTable]
SET [AnotherTable].TessereCorso = main.[J5F7NR]
FROM
(SELECT DISTINCT m.* FROM [MyTable] m) As main
INNER JOIN [AnotherTable]
ON (main.J5BINB = [AnotherTable].GKBINB)
AND (main.J5BHNB = [AnotherTable].GKBHNB)
AND (main.J5BDCD = [AnotherTable].GKBDCD)
Another variant of the query.. (Too lazy to get the original tables).
But like the query above updates 35 rows =, so does this one
UPDATE [Albi-Anagrafe-Associati]
SET
[Albi-Anagrafe-Associati].CRegDitte = [055- Registri ditte].[CRegDitte],
[Albi-Anagrafe-Associati].NIscrTribunale = [055- Registri ditte].[NIscrTribunale],
[Albi-Anagrafe-Associati].NRegImprese = [055- Registri ditte].[NRegImprese]
FROM [055- Registri ditte]
WHERE EXISTS(
SELECT *
FROM [055- Registri ditte]-- [Albi-Anagrafe-Associati]
WHERE ([055- Registri ditte].GIBINB = [Albi-Anagrafe-Associati].GKBINB)
AND ([055- Registri ditte].GIBHNB = [Albi-Anagrafe-Associati].GKBHNB)
AND ([055- Registri ditte].GIBDCD = [Albi-Anagrafe-Associati].GKBDCD))
Update [AnotherTable]
Set [AnotherTable].TessereCorso = MyTable.[J5F7NR]
From [AnotherTable]
Inner Join
(
Select Distinct [J5BINB],[5BHNB],[J5BDCD]
,(Select Top 1 [J5F7NR] From MyTable) as [J5F7NR]
,[J5BHNB]
From MyTable
)as MyTable
On (MyTable.J5BINB = [AnotherTable].GKBINB)
AND (MyTable.J5BHNB = [AnotherTable].GKBHNB)
AND (MyTable.J5BDCD = [AnotherTable].GKBDCD)

SQL update with count gets only nulls

I am using SQL Server 2008 R2 and SSRS 2008 to generate the report. I am trying to update a table to get a count of the results from another table.
UPDATE r
SET r.Race = d2.Race,
r.RaceNum = d2.count
FROM #results r
INNER JOIN
(SELECT d.Race,
COUNT(d.race) AS 'count'
FROM #Demographic d
GROUP BY d.Race)d2 ON r.Race = d2.Race
An insert works perfectly but I am inserting several times into the results table to create a demographics report. This is creating a lot Null data at the table of the results. If anyone has an idea of what I am going wrong the help would be appreciated.
Not certain, but first guess is that count is a reserved word... change it to something else such as...
update r
set r.Race = d2.Race, r.RaceNum = d2.cnt
from #results r
inner join
(select d.Race, COUNT(d.race) as 'cnt' from #Demographic d group by d.Race)d2
on r.Race = d2.Race
or alternatively try delimiting the column identifier as [count] or if you have quoted identifiers on "count"
Your query is:
update r
set r.Race = d2.Race, /*<---------*/
r.RaceNum = d2.count
from #results r inner join
(select d.Race, COUNT(d.race) as 'count'
from #Demographic d
group by d.Race
) d2
on r.Race = d2.Race /*<-------- */
The two marked lines stand out. You are joining on values using =, then you are setting one equal to the other. This may not be the problem, but it is suspicious. If you are joining on them, why are you setting them equal? My suspicion is that the join is failing, because nothing matches it.
You don't need to update the race column, since that's the equality portion of your join.
As written, any race not in #demographic would have its racenum set to null. If you want 0 for those try:
UDPATE
r
SET
r.RaceNum = ISNULL(d2.ct, 0)
FROM #results r
LEFT JOIN
(
SELECT
d.Race
, COUNT(d.race) as ct
FROM
#Demographic d
GROUP BY
d.Race
) d2
ON
r.Race = d2.Race

use stored procedure to select last item value

i am trying to select the last record value from my database by using stored procedure, to do this i set my #UPID parameter as SCORE_IDENTITY(), but there are no output result as all after i execute my stored procedure
CREATE PROCEDURE [dbo].[spAuditLogSelect_NewUser]
#UPID int
AS
BEGIN
SET #UPID = SCOPE_IDENTITY()
SELECT
siUserProfile.UPID
,siUserProfile.ProfileType, siProfileType.RGDName AS ProfileTypeName
,siUserProfile.CBID, siCompany.ComName + ' - ' + siComBranch.ComBranchName AS CBName
,siUserProfile.FullName
,siUserProfile.ShortName
,siUserProfile.SerialCode
,siUserProfile.Serial
,siUserProfile.Gender
from siUserProfile WITH (NOLOCK)
inner join siUserProfileDetail WITH (NOLOCK) on siUserProfile.upid = siUserProfileDetail.UPID
left outer join siReferenceGroupDetail siProfileType WITH (NOLOCK) ON siUserProfile.ProfileType = siProfileType.RGDID
left outer join siComBranch WITH (NOLOCK) on siComBranch.CBID = siUserProfile.CBID
left outer join siCompany WITH (NOLOCK) ON siComBranch.CompanyID = siCompany.CompanyID
where siUserProfile.UPID = #UPID
SCOPE_IDENTITY() is meant to be used right after insert. It won't work in a different session.
To retrieve the latest entry, try top 1:
select top 1 *
...
where siUserProfile.UPID = #UPID
order by
siUserProfile.ID desc
You require to use IDENT_CURRENT(‘tablename’).
Please refer below link which illustrate difference between ##IDENTITY,SCOPE_IDENTITY() and IDENT_CURRENT(‘tablename’).
http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/
Hope this will help you.
I am assuming that you have some primary key(PK) in your table. Write the procedure, in that procedure fire the query
select * from Your_Table where PK_Column in(select max(PK_Column) from Your_Table)
This way you will be able to fetch the latest record from DB. By opening a cursor, you can play with record in your procedure.