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

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

Related

SQL Inner Join and nearest row to date

I dont't get it. I changed some of the code. In the WPLEVENT Table are a lot of Events per person. In the Persab-Table are the Persons with their History. Now I need the from the Persab Table just that row wich matches the persab.gltab Date nearest to the WPLEVENT.vdat Date. So all rows from the WPLEVENT, but just the one matching row from the PERSAB-Table.
SELECT
persab.name,
persab.vorname,
vdat,
eventstart,
persab.rc1,
persab.rc2
FROM wplevent
INNER JOIN
persab ON WPLEVENT.PersID = persab.PRIMKEY
INNER JOIN
(SELECT TOP 1 persab.rc1
FROM PERSAB
WHERE persab.gltab <= getdate() --/ Should be wplevent.vdat instead of getdate()
) NewTable ON wplevent.persid = persab.primkey
WHERE
persid ='100458'
ORDER BY vdat DESC
Need to use the MAX() function with the proper syntax by supplying an expression like MAX(persab.rc1). Also need to use GROUP BY for the second column rc2 in the subquery (although it looks like you do not need it). Finally you are missing the ON clause for the final INNER JOIN. I can update the answer to fix the query if you provide that information.
SELECT
Z1PERS.NAME
, Z1PERS.VORNAME
, WPLEVENT.VDat
, WPLEVENT.EventStart
, WPLEVENT.EventStop
, WPLEVENT.PEPGROUP
, Z1SGRP.TXXT
, PERSAB.GLTAB
, Z1PERS.PRIMKEY AS Expr1
, PERSAB.PRIMKEY
FROM
Z1PERS
INNER JOIN
WPLEVENT ON Z1PERS.PRIMKEY = WPLEVENT.PersID
INNER JOIN
Z1SGRP ON WPLEVENT.PEPGROUP = Z1SGRP.GRUPPE
INNER JOIN
(
SELECT MAX(Persab.rc1) --Fixed MAX expression
, persab.rc2
FROM
persab
GROUP BY
persab.rc2 --Need to group on rc2 if you want that column in the query otherwise remove this AND the rc2 column from select list
WHERE
WPLEVENT.PersID = PERSAB.PRIMKEY
AND WPLEVENT.VDat <= PERSAB.GLTAB
) --Missing ON clause for the INNER JOIN here
WHERE z1pers.vorname = 'henning'

How can I perform the Count function with a where clause?

I have my database setup to allow a user to "Like" or "Dislike" a post. If it is liked, the column isliked = true, false otherwise (null if nothing.)
The problem is, I am trying to create a view that shows all Posts, and also shows a column with how many 'likes' and 'dislikes' each post has. Here is my SQL; I'm not sure where to go from here. It's been a while since I've worked with SQL and everything I've tried so far has not given me what I want.
Perhaps my DB isn't setup properly for this. Here is the SQL:
Select trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname, Count(trippin.LikesDislikesData.liked)
as TimesLiked from trippin.PostData
inner join trippin.AccountData on trippin.PostData.accountid = trippin.AccountData.id
inner join trippin.CategoryData on trippin.CategoryData.id = trippin.PostData.categoryid
full outer join trippin.LikesDislikesData on trippin.LikesDislikesData.postid =
trippin.PostData.id
full outer join trippin.LikesDislikesData likes2 on trippin.LikesDislikesData.accountid =
trippin.AccountData.id
Group By (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
Here's my table setup (I've only included relevant columns):
LikesDislikesData
isliked(bit) || accountid(string) || postid(string
PostData
id(string) || posttext || accountid(string)
AccountData
id(string) || username(string)
CategoryData
categoryname(string)
Problem 1: FULL OUTER JOIN versus LEFT OUTER JOIN. Full outer joins are seldom what you want, it means you want all data specified on the "left" and all data specified on the "right", that are matched and unmatched. What you want is all the PostData on the "left" and any matching Likes data on the "right". If some right hand side rows don't match something on the left, then you don't care about it. Almost always work from left to right and join results that are relevant.
Problem 2: table alias. Where ever you alias a table name - such as Likes2 - then every instance of that table within the query needs to use that alias. Straight after you declare the alias Likes2, your join condition refers back to trippin.LikesDislikesData, which is the first instance of the table. Given the second one in joining on a different field I suspect that the postid and accountid are being matched on the same row, therefore it should be AND together, not a separate table instance. EDIT reading your schema closer, it seems this wouldn't be needed at all.
Problem 3: to solve you Counts problem separate them using CASE statements. Count will add the number of non NULL values returned for each CASE. If the likes.liked = 1, then return 1 otherwise return NULL. The NULL will be returned if the columns contains a 0 or a NULL.
SELECT trippin.PostData.Id, trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname,
SUM(CASE WHEN likes.liked = 1 THEN 1 ELSE 0 END) as TimesLiked,
SUM(CASE WHEN likes.liked = 0 THEN 1 ELSE 0 END) as TimesDisLiked
FROM trippin.PostData
INNER JOIN trippin.AccountData ON trippin.PostData.accountid = trippin.AccountData.id
INNER JOIN trippin.CategoryData ON trippin.CategoryData.id = trippin.PostData.categoryid
LEFT OUTER JOIN trippin.LikesDislikesData likes ON likes.postid = trippin.PostData.id
-- remove AND likes.accountid = trippin.AccountData.id
GROUP BY trippin.PostData.Id, (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
Then "hide" the PostId column in the User Interface.
Instead of selecting Count(trippin.LikesDislikesData.liked) you could put in a select statement:
Select AccountData.username, PostData.posttext, CategoryData.categoryname,
(select Count(*)
from LikesDislikesData as likes2
where likes2.postid = postdata.id
and likes2.liked = 'like' ) as TimesLiked
from PostData
inner join AccountData on PostData.accountid = AccountData.id
inner join CategoryData on CategoryData.id = PostData.categoryid
USE AdventureWorksDW2008R2
GO
SET NOCOUNT ON
GO
/*
Default
*/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRAN
IF OBJECT_ID('tempdb.dbo.#LikesDislikesData') IS NOT NULL
BEGIN
DROP TABLE #LikesDislikesData
END
CREATE TABLE #LikesDislikesData(
isLiked bit
,accountid VARCHAR(50)
,postid VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#PostData') IS NOT NULL
BEGIN
DROP TABLE #PostData
END
CREATE TABLE #PostData(
postid INT IDENTITY(1,1) NOT NULL
,accountid VARCHAR(50)
,posttext VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#AccountData') IS NOT NULL
BEGIN
DROP TABLE #AccountData
END
CREATE TABLE #AccountData(
accountid INT
,username VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#CategoryData') IS NOT NULL
BEGIN
DROP TABLE #CategoryData
END
CREATE TABLE #CategoryData(
categoryname VARCHAR(50)
);
INSERT INTO #AccountData VALUES ('1', 'user1')
INSERT INTO #PostData VALUES('1','this is a post')
INSERT INTO #LikesDislikesData (isLiked ,accountid, postid)
SELECT '1', P.accountid, P.postid
FROM #PostData P
WHERE P.posttext = 'this is a post'
SELECT *
FROM #PostData
SELECT *
FROM #LikesDislikesData
SELECT *
FROM #AccountData
SELECT COUNT(L.isLiked) 'Likes'
,P.posttext
,A.username
FROM #PostData P
JOIN #LikesDislikesData L
ON P.accountid = L.accountid
AND L.IsLiked = 1
JOIN #AccountData A
ON P.accountid = A.accountid
GROUP BY P.posttext, A.username
SELECT X.likes, Y.dislikes
FROM (
(SELECT COUNT(isliked)as 'likes', accountid
FROM #LikesDislikesData
WHERE isLiked = 1
GROUP BY accountid
) X
JOIN
(SELECT COUNT(isliked)as 'dislikes', accountid
FROM #LikesDislikesData
WHERE isLiked = 0
GROUP BY accountid) Y
ON x.accountid = y.accountid)
IF (XACT_STATE() = 1 AND ERROR_STATE() = 0)
BEGIN
COMMIT TRAN
END
ELSE IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN
END
How do you think about the solution? We create a new table SummaryReport(PostID,AccountID,NumberOfLikedTime,NumberOfDislikedTimes).
An user clicks on LIKE or DISLIKE button we update the table. After that, you can query as you desire. Another advantage, the table can be served reporting purpose.

Query returns a different result every time it is run

This query always returns the same amount of rows but, in a different order, every time. Why does this happen?
I have more filters to add but I can't get past this step.
BEGIN
DECLARE #lastStatus Varchar(10)
SELECT
[Job].[Job],
[Job].[Part_Number],
[Job].[Rev],
[Job_Operation].[Description],
[Job].[Customer_PO],
[Job].[Customer_PO_LN],
[Delivery].[Promised_Date],
[Job_Operation].[Operation_Service],
[Job].[Note_Text],
[Job_Operation].[Status],
[Job_Operation].[Sequence]
INTO [#tmpTbl]
FROM [PRODUCTION].[dbo].[Job_Operation]
INNER JOIN [Job]
ON [Job_Operation].[Job]=[Job].[Job]
INNER JOIN [Delivery]
ON [Job_Operation].[Job]=[Delivery].[Job]
WHERE [Job].[Status]='Complete'
ORDER BY [Job_Operation].[Job],[Job_Operation].[Sequence]
SELECT *
FROM [#tmpTbl]
DROP TABLE [#tmpTbl]
END
Put the Order By on the Select * From #tmpTbl, not on the insert.
Hi you can do initials on your table and you can remove your bracket for non spaces so you can make your code shorter.
SELECT j.Job,
,j.[Part_Number]
,j.Rev
,j_O.Description
,j.Customer_PO
,j.[Customer_PO_LN]
,d.[Promised_Date]
,j_o.[Operation_Service]
,j.[Note_Text],
,j_o.Status,
,j_o.Sequence
,j.[Customer_PO],
,j.[Customer_PO_LN],
,d.[Promised_Date],
,j_o.[Operation_Service],
,j.[Note_Text],
,j_o.[Status],
[Job_Operation].[Sequence]
INTO [#tmpTbl]
FROM [PRODUCTION].[dbo].[Job_Operation] j_o
INNER JOIN Job j
ON j_o.Job = j.Job
INNER JOIN Delivery d
ON j_o.Job= d.Job
WHERE j.Status='Complete'
ORDER BY j_o.Job,j_o.Sequence
SELECT *
FROM [#tmpTbl]
DROP TABLE [#tmpTbl]
END
Because you don't have an order by clause when you select from #tmpTbl
Try
SELECT *
FROM [#tmpTbl]
ORDER BY Job, Sequence
You cannot specify the order data goes into a table through a SET command (i.e. SELECT INTO) - that is determined by whether the table has a clustered index defined after it's created.
You control the order of the data when you're eventually selecting FROM that table to get your results.
SELECT * FROM [#tmpTbl] ORDER BY ....

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.

How can I select none duplicate rows with inner join?

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 ...