Getting error tb_sales_person_source.id is invalid in the select list in SQL Server - sql

I am new to SQL Server, I have below query which is working fine in Mysql server, but it is not working in SQL Server, I get an error:
tb_sales_person_source.id is invalid in the select list
Can anyone please help me how can I resolve this error ?
SELECT
tb_sales_person_source.id,
tb_sales_person_source.name,
tb_sales_person_source.display_name,
tb_sales_person_source.mapped_sales_person_source_id,
tb_sales_person_source.company_id,
tb_sales_person_source.gm_created,
tb_sales_person_source.gm_modified,
COUNT(tb_Episode.id) AS total_soc,
SOCDate, MonthSOC
FROM
tb_Episode
JOIN
tb_sales_person_source ON tb_sales_person_source.id = tb_Episode.sales_referral_source_id
WHERE
(BranchID = '238' OR BranchID = '239' OR BranchID = '240' OR BranchID = '241')
AND tb_Episode.CustID = '27'
AND PayerType = 'Ep'
AND SOC = 1
AND SOCDate >= '2016-04-01'
AND SOCDate < '2017-5-01'
GROUP BY
sales_referral_source_id, MonthSOC
ORDER BY
tb_sales_person_source.id ASC, tb_Episode.SOCDate ASC;

In SQL server, you must have to add all the columns of "SELECT" in "Group by" apart from the column which is used in the aggregate function
SELECT tb_sales_person_source.id
,tb_sales_person_source.NAME
,tb_sales_person_source.display_name
,tb_sales_person_source.mapped_sales_person_source_id
,tb_sales_person_source.company_id
,tb_sales_person_source.gm_created
,tb_sales_person_source.gm_modified
,count(tb_Episode.id) AS total_soc
,SOCDate
,MonthSOC
FROM tb_Episode
JOIN tb_sales_person_source ON tb_sales_person_source.id = tb_Episode.sales_referral_source_id
WHERE (
BranchID = '238'
OR BranchID = '239'
OR BranchID = '240'
OR BranchID = '241'
)
AND tb_Episode.CustID = '27'
AND PayerType = 'Ep'
AND SOC = 1
AND SOCDate >= '2016-04-01'
AND SOCDate < '2017-5-01'
GROUP BY sales_referral_source_id
,MonthSOC
,tb_sales_person_source.id
,tb_sales_person_source.NAME
,tb_sales_person_source.display_name
,tb_sales_person_source.mapped_sales_person_source_id
,tb_sales_person_source.company_id
,tb_sales_person_source.gm_created
,tb_sales_person_source.gm_modified
,SOCDate
ORDER BY tb_sales_person_source.id ASC
,tb_Episode.SOCDate ASC

It is impossible to accurately re-write your query until you update it to make it clear which table each column comes from.
The important piece of information you need to be aware of, however, is that when using GROUP BY every field in the SELECT must either have an aggregate function around it (MIN(), or MAX(), or SUM(), etc, etc), or be mentioned in the GROUP BY.
This means that the following is NOT valid SQL...
SELECT
t1.some_id,
t1.name,
t1.whatever,
COUNT(t2.id),
SUM(t2.value)
FROM
t1
INNER JOIN
t2
ON t2.some_id = t1.some_id
GROUP BY
t1.some_id
Instead you need one of the following...
SELECT
t1.some_id ,
t1.name,
t1.whatever,
COUNT(t2.id),
SUM(t2.value)
FROM
t1
INNER JOIN
t2
ON t2.some_id = t1.some_id
GROUP BY
t1.some_id,
t1.name,
t1.whatever
Or...
SELECT
t1.some_id,
MAX(t1.name),
MAX(t1.whatever),
COUNT(t2.id),
SUM(t2.value)
FROM
t1
INNER JOIN
t2
ON t2.some_id = t1.some_id
GROUP BY
t1.some_id
The same is true even if you are grouping by a column from table 2.
So, this is invalid too...
SELECT
t1.some_id,
t1.name,
t2.a_date,
COUNT(t2.id),
SUM(t2.value)
FROM
t1
INNER JOIN
t2
ON t2.some_id = t1.some_id
GROUP BY
t2.a_date
This time, however, you have an extra option. Use a sub-query to group up the data in table 2 first...
SELECT
t1.some_id,
t1.name,
t2_agg.a_date,
t2_agg.count_rows,
t2_agg.total_value
FROM
t1
INNER JOIN
(
SELECT
some_id,
a_date,
COUNT(t2.id) AS count_rows,
SUM(t2.value) AS total_value
FROM
t2
GROUP BY
some_id,
a_date
)
t2_agg
ON t2_agg.some_id = t1.some_id
If you fully qualify your query (so I can see which table every column comes from) then I can show you how to use this method to suit your exact case.

Finally i resolved my query, here is my query, thanks to all of you for your help
SELECT tb_sales_person_source.id, tb_sales_person_source.name, tb_sales_person_source.display_name, count(tb_Episode.id) as total_soc, MonthSOC
FROM tb_Episode
JOIN tb_sales_person_source ON tb_sales_person_source.id = tb_Episode.sales_referral_source_id
WHERE ( BranchID = '238' or BranchID = '239' or BranchID = '240' or BranchID = '241')
AND tb_Episode.CustID = '27'
AND PayerType = 'Ep'
AND SOC = 1
AND SOCDate >= '2016-04-01'
AND SOCDate < '2017-5-01'
GROUP BY tb_sales_person_source.id, tb_sales_person_source.name, tb_sales_person_source.display_name, sales_referral_source_id, MonthSOC
ORDER BY tb_sales_person_source.id asc

Related

Query to get the line with the latest date

SELECT T0.[ItemCode], T0.[PriceFOB], T0.[PriceAtWH], T0.[DocEntry], T0.[CardCode], T2.[DocDate], T3.[CardName] FROM IPF1 T0 LEFT JOIN OIPF T2 ON T2.[DocDate] = (SELECT MAX(T4.[DocDate]) FROM OIPF T4 WHERE T0.[DocEntry]=T4.[DocEntry]) INNER JOIN OCRD T3 ON T0.[CardCode] = T3.[CardCode] WHERE T3.[GroupCode] = '105'
I am using the following query listed above.
The issue rises where I have multiple lines of the same item listed but my goal is to get the one with the LATEST DocDate.
If someone can please help and explain what it is that I am doing wrong.
I have tried Order By, Group By but keep getting multiple errors (syntax mostly)
SELECT ItemCode, PriceAtWH, DocEntry, PriceFOB, CardCode FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY T0.[ItemCode] ORDER BY T0.[DocEntry] DESC) AS ROWNUM FROM IPF1 T0) IPF1 WHERE ROWNUM = 1
This is the other query that I was able to come close to my solution but I need it to filter for only GroupCode = '105' from OCRD matching the CardCode
The Main goal is to filter out a Master DATA which is combined with IPF1 and OCRD(Only need to pull Group Code from this) and to filter the IPF1 with the Group Code first. Then proceed to do the Max Date or Max DocEntry ID for each item.
You could use a distinct to get one row per event even if they have different dates and use the MAX on the select
SELECT distinct T0.[ItemCode],
T0.[PriceFOB],
T0.[PriceAtWH],
T0.[DocEntry],
T0.[CardCode],
T3.[CardName],
MAX(T2.[DocDate] ) DocDate
FROM IPF1 T0
LEFT JOIN OIPF T2
ON T0.[DocEntry]=T2.DocEntry]
INNER JOIN OCRD T3
ON T0.[CardCode] = T3.[CardCode]
WHERE T3.[GroupCode] = '105'
GROUP BY T0.[ItemCode], T0.[PriceFOB], T0.[PriceAtWH], T0.[DocEntry], T0.[CardCode],T3.[CardName]
WITH T AS (SELECT T10.[DocEntry], T10.[CardCode], T10.[ItemCode], T10.[PriceFOB], T10.[PriceAtWH] FROM IPF1 T10 INNER JOIN OCRD T11 ON T10.[CardCode] = T11.[CardCode] WHERE T11.[GroupCode] = '105')
SELECT T.[DocEntry], T.[CardCode], T.[ItemCode], T.[PriceFOB], T.[PriceAtWH] FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY T.[ItemCode] ORDER BY T.[DocEntry] DESC) AS ROWNUM FROM T) T WHERE ROWNUM = 1
So I ended up solving my own problem.
Thank you Julissa for trying buy your query has an error where you are missing a "[" in front of DocEntry and also the query does not do what I want it do, multiple instances of the same item for all date still show up. Thank you for trying!

subquery uses ungrouped column "omt.actualendtime" from outer query

Following is the query
SELECT omt.actualendtime::date,
(SELECT array_to_json(array_agg(row_to_json(t)))
FROM (SELECT odt.productshortname,
count(odt.*)
FROM orderdetail_runtime_tran odt
WHERE odt.actualendtime::date = omt.actualendtime::date
AND odt.stagename = 'Ironing'
GROUP BY odt.productshortname
) t
) as item_current_count
From orderdetail_runtime_tran omt
WHERE omt.actualendtime IS NOT NULL AND date_part('year', omt.actualendtime) = '2019'
AND omt.stagename = 'Ironing'
GROUP BY omt.actualendtime::date;
This query is giving error
subquery uses ungrouped column "omt.actualendtime" from outer query
Try using a subquery:
SELECT actualenddate,
(SELECT array_to_json(array_agg(row_to_json(t)))
FROM (SELECT odt.productshortname, count(odt.*)
FROM orderdetail_runtime_tran odt
WHERE odt.actualendtime::date = actualenddate AND
odt.stagename = 'Ironing'
GROUP BY odt.productshortname
) t
) as item_current_count
FROM (SELECT omt.*,
omt.actualendtime::date as actualenddate
FROM orderdetail_runtime_tran omt
WHERE omt.actualendtime IS NOT NULL AND
date_part('year', omt.actualendtime) = '2019' AND
omt.stagename = 'Ironing'
) omt
GROUP BY actualenddate;

How can I get value from above row with same ID if row is null?

I'm new with SQL and I encountered this.
Here's a screenshot
My question is how can I make all the NULL on primary_payer_id get the value above only if they have same ClientID and ActionCode IS NOT NULL. FYI CustomColumn is only a copy of primary_payer_id ALSO I attached my code here below.
Here's my code:
SELECT ci.client_id AS ClientID,
ci.primary_payer_id,
ci.effective_date AS EffectiveDate,
ci.action_code_id AS ActionCode,
cc.item_description AS ItemDesc,
ap.description AS IDescription,
ci.deleted
FROM census_item ci
LEFT JOIN common_code cc ON ci.adt_tofrom_id = cc.item_id
LEFT JOIN ar_lib_payers ap ON ci.primary_payer_id = ap.payer_id
WHERE ci.deleted = 'N'
There might be a more efficient method, but this will work:
with t as (
<your query here>
)
select t.*,
(case when t.actioncode is not null and t.clientid is null
then tprev.clientid
else t.clientid
end) as new_clientid
from t outer apply
(select top 1 tprev.*
from t tprev
where tprev.clientid = t.clientid and
tprev.effectivedate < t.effectivedate
order by tprev.effecctivedate desc
) tprev;

Write query using JOINS

select
store, sum(value)
from
rms.sa_tran_head
where
store_day_seq_no in (select store_day_seq_no
from rms.sa_store_day
where store in (3003)
and business_date = '01-JAN-2015')
and tran_type in ('SALE', 'RETURN')
group by
store;
How to write the above query using JOINS..
SELECT
sd.store,
SUM(TH.VALUE) AS GROSS ,
SUM(ti.qty) AS QTY
FROM rms.sa_tran_head AS th
JOIN rms.sa_store_day AS sd
ON th.store_day_seq_no = sd.store_day_seq_no
JOIN rms.sa_tran_item AS ti
ON ti.tran_seq_no = th.tran_seq_no
WHERE sd.store in (3003) --in (3003) use in if more than 1 value
AND sd.business_date = '01-JAN-2015'
AND th.tran_type IN ('SALE','RETURN')
GROUP BY
sd.store;
When I add other columns of another table it is showing different values...
I assumed store_day_seq_no is FK for the table rms.sa_store_day and the query with JOIN like this,
SELECT
sd.store,
SUM(sd.value) AS [Sum]
FROM rms.sa_tran_head AS th
JOIN rms.sa_store_day AS sd
ON th.store_day_seq_no = sd.store_day_seq_no
WHERE
sd.store = 3003 --in (3003) use in if more than 1 value
AND sd.business_date = '01-JAN-2015'
AND th.tran_type IN ('SALE','RETURN')
GROUP BY
sd.store;
I think this is ok.
SELECT
t1.store,
SUM(t1.Value) AS Sum_Value
FROM rms.sa_tran_head t1
INNER JOIN sa_store_day t2 ON t1.store_day_seq_no = t2.store_day_seq_no
WHERE t2.store IN ( 3003 )
AND t2.business_date = '01-JAN-2015'
AND t1.tran_type IN ( 'SALE' , 'RETURN' )
GROUP BY t1.store

Inner join that ignore singlets

I have to do an self join on a table. I am trying to return a list of several columns to see how many of each type of drug test was performed on same day (MM/DD/YYYY) in which there were at least two tests done and at least one of which resulted in a result code of 'UN'.
I am joining other tables to get the information as below. The problem is I do not quite understand how to exclude someone who has a single result row in which they did have a 'UN' result on a day but did not have any other tests that day.
Query Results (Columns)
County, DrugTestID, ID, Name, CollectionDate, DrugTestType, Results, Count(DrugTestType)
I have several rows for ID 12345 which are correct. But ID 12346 is a single row of which is showing they had a row result of count (1). They had a result of 'UN' on this day but they did not have any other tests that day. I want to exclude this.
I tried the following query
select
c.desc as 'County',
dt.pid as 'PID',
dt.id as 'DrugTestID',
p.id as 'ID',
bio.FullName as 'Participant',
CONVERT(varchar, dt.CollectionDate, 101) as 'CollectionDate',
dtt.desc as 'Drug Test Type',
dt.result as Result,
COUNT(dt.dru_drug_test_type) as 'Count Of Test Type'
from
dbo.Test as dt with (nolock)
join dbo.History as h on dt.pid = h.id
join dbo.Participant as p on h.pid = p.id
join BioData as bio on bio.id = p.id
join County as c with (nolock) on p.CountyCode = c.code
join DrugTestType as dtt with (nolock) on dt.DrugTestType = dtt.code
inner join
(
select distinct
dt2.pid,
CONVERT(varchar, dt2.CollectionDate, 101) as 'CollectionDate'
from
dbo.DrugTest as dt2 with (nolock)
join dbo.History as h2 on dt2.pid = h2.id
join dbo.Participant as p2 on h2.pid = p2.id
where
dt2.result = 'UN'
and dt2.CollectionDate between '11-01-2011' and '10-31-2012'
and p2.DrugCourtType = 'AD'
) as derived
on dt.pid = derived.pid
and convert(varchar, dt.CollectionDate, 101) = convert(varchar, derived.CollectionDate, 101)
group by
c.desc, dt.pid, p.id, dt.id, bio.fullname, dt.CollectionDate, dtt.desc, dt.result
order by
c.desc ASC, Participant ASC, dt.CollectionDate ASC
This is a little complicated because the your query has a separate row for each test. You need to use window/analytic functions to get the information you want. These allow you to do calculate aggregation functions, but to put the values on each line.
The following query starts with your query. It then calculates the number of UN results on each date for each participant and the total number of tests. It applies the appropriate filter to get what you want:
with base as (<your query here>)
select b.*
from (select b.*,
sum(isUN) over (partition by Participant, CollectionDate) as NumUNs,
count(*) over (partition by Partitipant, CollectionDate) as NumTests
from (select b.*,
(case when result = 'UN' then 1 else 0 end) as IsUN
from base
) b
) b
where NumUNs <> 1 or NumTests <> 1
Without the with clause or window functions, you can create a particularly ugly query to do the same thing:
select b.*
from (<your query>) b join
(select Participant, CollectionDate, count(*) as NumTests,
sum(case when result = 'UN' then 1 else 0 end) as NumUNs
from (<your query>) b
group by Participant, CollectionDate
) bsum
on b.Participant = bsum.Participant and
b.CollectionDate = bsum.CollectionDate
where NumUNs <> 1 or NumTests <> 1
If I understand the problem, the basic pattern for this sort of query is simply to include negating or exclusionary conditions in your join. I.E., self-join where columnA matches, but columns B and C do not:
select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
and t1.PkId != t2.PkId
and t1.category != t2.category
)
Put the conditions in the WHERE clause if it benchmarks better:
select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
)
where
t1.PkId != t2.PkId
and t1.category != t2.category
And it's often easiest to start with the self-join, treating it as a "base table" on which to join all related information:
select
[columns]
from
(select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
)
where
t1.PkId != t2.PkId
and t1.category != t2.category
) bt
join [othertable] on (<whatever>)
join [othertable] on (<whatever>)
join [othertable] on (<whatever>)
This can allow you to focus on getting that self-join right, without interference from other tables.