SQL sub query not working with group by clause - sql

I am using SQL Server 2012. Can anyone tell me where i am going wrong ?
SELECT
avg ( tbl.FirstBillComplete )
FROM
( select l.MONTH, a.OverallScore, (a.FirstBillComplete), ( a.EmailComplete)
from tbl_T1 a join calls.dbo.c1_LP l on a.QID = l.QID
union
select l.MONTH, a.OverallScore, (a.FirstBillComplete), ( a.EmailComplete)
from tbl_2 a join calls.dbo.C3_LP l on a.QID = l.QID
union ALL
select l.MONTH, a.OverallScore, (a.FirstBillComplete), ( a.EmailComplete)
from tbl_3 a join c2 l on a.QID = l.QID
) As tbl
GROUP BY tbl.MONTH
The error I get is :
No column was specified for column 7 of 'tbl'.
No column was specified for column 8 of 'tbl'

You need to specify a column name for column 7 and 8 of tbl: use
'' AS MyColumn7,
For example.

Related

Optimizing SQL Cross Join that checks if any array value in other column

Let's say I have a table events with structure:
id
value_array
XXXX
[a,b,c,d]
...
...
I have a second table values_of_interest with structure:
value
x
y
z
a
I want to find id's that have any of the values found in values_of_interest. All else equal, what would be the most performant SQL to make this happen? (I am using BigQuery, but feel free to answer more generally)
My current thought is:
SELECT
DISTINCT e.id
FROM
events e, values_of_interest vi
WHERE
EXISTS(
SELECT
value
FROM
UNNEST(e.value_array) value
JOIN
vi ON vi.value = e.value
)
Few quick options for BigQuery Standard SQL
Option 1
select id
from `project.dataset.events`
where exists (
select 1
from `project.dataset.values_of_interest`
where value in unnest(value_array)
)
Option 2
select id
from `project.dataset.events` t
where (
select count(1)
from t.value_array as value
join `project.dataset.values_of_interest`
using(value)
) > 0
I would write this using exists and a join:
select e.id
from `project.dataset.events` e
where exists (select 1
from unnest(e.value_array) val join
`project.dataset.values_of_interest` voi
on val = voi.value
);

how to set expression variable in query select oracle sql

I have Oracle SQL like these :
SELECT
z."date", z.id_outlet as idOutlet, z.name as outletName, z.matClass, z.targetBulanan, z.targetBulanan/totalVisit as targetAwal,
z.actual,rownumber = tartot + rownumber as targetTotal
FROM (SELECT
b.visit_date as "date", a.id_outlet, max(o.name) as name, max(a.target_sales) as targetBulanan, a.id_material_class as matClass,
max(x.totalVisit) as totalVisit, NVL(SUM(d.billing_value),0) as actual
FROM (
select * from target_bulanan
where deleted = 0 and enabled = 1 and id_salesman = :id_salesman AND id_material_class like :id_material_class AND id_outlet like :id_outlet AND month = TO_NUMBER(TO_CHAR(current_date,'mm')) and year = to_number(TO_CHAR(current_date,'YYYY'))
) a
INNER JOIN outlet o ON o.id_outlet = a.id_outlet
LEFT JOIN visit_plan b ON b.deleted = 0 and a.id_salesman = b.id_salesman AND a.month = TO_NUMBER(TO_CHAR(b.visit_date,'mm')) AND a.year = to_number(TO_CHAR(b.visit_date,'yyyy')) AND a.id_outlet = b.id_outlet
LEFT JOIN so_header c ON SUBSTR(c.id_to,'0',1) = 'TO' AND a.id_salesman = c.id_salesman AND a.id_outlet = c.id_outlet
LEFT JOIN assign_billing d ON c.no_so_sap = d.no_so_sap AND d.billing_date = b.visit_date AND a.id_material_class = (SELECT id_material_class FROM material WHERE id = d.id_material)
LEFt JOIN (SELECT id_salesman, to_char(visit_date,'mm') as month, to_char(visit_date,'yyyy') as year, id_outlet, COUNT(*) as totalVisit FROM visit_plan
WHERE deleted = 0
group by id_salesman, id_outlet,to_char(visit_date,'mm'), to_char(visit_date,'yyyy')) x on
x.id_salesman = a.id_salesman AND x.month = a.month AND x.year = a.year AND x.id_outlet = a.id_outlet
GROUP BY b.visit_date, a.id_outlet, a.id_material_class) z
CROSS JOIN (SELECT 0 as rownumber FROM DUAL ) r
CROSS JOIN (SELECT 0 as tartot FROM DUAL ) t
CROSS JOIN (SELECT '' as mat FROM DUAL ) m
CROSS JOIN (SELECT '' as outlet FROM DUAL ) o
ORDER by outletName, z.matClass, z."date"
I want value of rownumber is formula in my select query but the result is error with this message
ORA-00923: FROM keyword not found where expected
00923. 00000 - "FROM keyword not found where expected"
Anyone can help me ? thanks
Just for enumeration -
replace the line
rownumber = rownumber + 1 AS row_number
with this
rownum AS row_number
rownum is an Oracle inbuilt function that enumerates each record of the result set and with auto increments
As mentioned by Gordon Linoff in his answer, there are further problems in your query.
At the first look (without executing it), I could list the problematic lines -
AND month = TO_NUMBER(TO_CHAR(current_date,'mm'))
AND year = to_number(TO_CHAR(current_date,'YYYY'))
Instead of current_date use sysdate
LEFT JOIN so_header c ON SUBSTR(c.id_to,'0',1) = 'TO'
I guess, you meant to do this -
LEFT JOIN so_header c ON SUBSTR(c.id_to,0,2) = 'TO'
i.e. substring from index 0 upto 2 characters
Plus, no need of those cross joins
THIS ADDRESSES THE ORIGINAL QUESTION.
You may have multiple problems in your query. After all, the best way to debug and to write queries is to start simple and gradually add complexity.
But, you do have an obvious error. In your outermost select:
SELECT z."date", z.id_outlet as idOutlet, z.name as outletName,
z.matClass, z.targetBulanan, z.targetBulanan/totalVisit as targetAwal,
z.actual,
rownumber = rownumber + 1 as row_number
The = is not Oracle syntax -- it looks like a SQL Server extension for naming a column or a MySQL use of variables.
I suspect that you want to enumerate the rows. If so, one syntax is row_number():
SELECT z."date", z.id_outlet as idOutlet, z.name as outletName,
z.matClass, z.targetBulanan, z.targetBulanan/totalVisit as targetAwal,
z.actual,
row_number() over (order by outletName, z.matClass, z."date") as row_number
In Oracle, you could also do:
rownum as row_number

SQL hide rows specifically

This is my table structure and sample rows:
And I have a SQL query like this :
WITH Test(ObjId, ObjectIcerik, KeyMi) AS
(
SELECT
ObjId, ObjectIcerik, KeyMi
FROM
Tek
WHERE
ObjId = 8
UNION ALL
SELECT
T.ObjId, T.ObjectIcerik, T.KeyMi
FROM
Tek T
INNER JOIN
Test as TE ON T.ObjParent = TE.ObjId
)
SELECT *
FROM Test
This is the result :
But I also need to hide parent and child rows if parent's KeyMi column is '1'.
What do I need to change in the SQL query to do this?
You should be able to just add the condition to the recursive CTE:
WITH Test(ObjId, ObjectIcerik, KeyMi) AS (
SELECT ObjId, ObjectIcerik, KeyMi FROM Tek
WHERE ObjId = 8 AND (KeyMI <> 1 OR KeyMI IS NULL)
UNION ALL
SELECT T.ObjId, T.ObjectIcerik, T.KeyMi
FROM Tek T INNER JOIN
Test TE
ON T.ObjParent = TE.ObjId
WHERE (t.KeyMI <> 1 OR t.KeyMI IS NULL)
)
SELECT *
FROM Test ;

INNER JOINING THE TABLE ITSELF GIVES No column name was specified for column 2

SELECT *
FROM
construction AS T2
INNER JOIN
(
SELECT project,MAX(report_date)
FROM construction
GROUP BY project
) AS R
ON T2.project=R.project AND T2.report_date=R.report_date
getting this error. plz help
No column name was specified for column 2 of 'R'
You need to add alias for MAX(report_date):
SELECT *
FROM construction AS T2
INNER JOIN
(
SELECT project,MAX(report_date) AS report_date
FROM construction
GROUP BY project
) AS R
ON T2.project = R.project
AND T2.report_date = R.report_date;
In SQL Server you can use syntax:
SELECT *
FROM construction AS T2
INNER JOIN
(
SELECT project,MAX(report_date)
FROM construction
GROUP BY project
) AS R(project, report_date)
ON T2.project = R.project
AND T2.report_date = R.report_date;
You should specific the MAX(report_date) with an alias report_date.
Because your table R have two columns project,MAX(report_date).
You are getting this error because you have not specified column name for inner query
You have to write your query as
SELECT *
FROM construction
INNER JOIN
(
SELECT project,MAX(report_date)"Max_ReportDate"
FROM construction
GROUP BY project
) Max_construction
ON construction.project = Max_construction .project
AND construction.report_date = Max_construction .Max_ReportDate

Remove repeated values from the table

I have a PL/SQL select query like,
select
a.sgm,
b.numbr
from tbl1 a, tbl2 b
where b.itemId = a.itemId
and b.orgId = a.orgId
and a.srvCode = 'F'
and a.nbrCode <> 1
and rownum <= 7
Right now it retrieves like ,
sgm-|-numbr
-----------
abc-|-123
abc-|-678
abc-|-78
abc-|-099
bcd-|-153
bcd-|-123
bcd-|-123
I need to retrieve like ,
sgm-|-numbr
-----------
abc-|-123
bcd-|-153
ie, I need to remove the repeated ones in the first column. ie sgm shouldn't repeat.
Since you are using Oracle, then try this simplified version using a CTE:
WITH CTE as (
SELECT sgm, numbr,
rownum rn
FROM YourTable
)
SELECT CTE.sgm, CTE.numbr
FROM CTE
JOIN (
SELECT sgm, MIN(rownum) minrn
FROM CTE
GROUP BY sgm) t ON CTE.sgm = t.sgm AND CTE.rn = t.minrn
http://sqlfiddle.com/#!4/8d6fb/10
You can replace your query in the CTE above.
Good luck.
SELECT a.sgm, MAX(b.numbr)
FROM tbl1 a INNER JOIN tbl2 b
ON a.itemID = b.itemId
AND a.orgId = b.orgId
WHERE a.srvCode= 'F'
AND a.nbrCode <> 1
AND rownum <= 7
GROUP BY a.sgm
Apply a group function of your choice like MAX() on b.numbr, and apply the grouping on a.sgm, this should do what you need.
Advice : do your joins explicitly, see the difference between your query and mine.
select a.sgm,MAX(b.numbr)
from tbl1 a, tbl2 b
where b.itemId = a.itemId
AND b.orgId= a.orgId
and a.srvCode= 'F'
and a.nbrCode <> 1
and rownum<=7
group by sgm
The value of sgm wont repeat, but maximum value of number will be selected, similarly you can also select the minimum value using the Min function
Use group by function
select
a.sgm,
b.numbr
from tbl1 a, tbl2 b
where b.itemId = a.itemId
and b.orgId = a.orgId
and a.srvCode = 'F'
and a.nbrCode <> 1
and rownum <= 7
group by a.sgm
Select a from tbl a , tbl b WHERE a.userid > b..userid and
a.sgm = b.sgm;
Check this fiddle http://sqlfiddle.com/#!2/40b8f/2