Error when Count rows from 2 Tables in Access - ms-access-2007

I want to count the number of rows from 2 tables based on my terms, in Microsoft Office Access 2007, but when I ran the SQL statement, I got this message :
"the microsoft office access database engine cannot find the input
table or query 'dual'. make sure it exist and that its name is spelled
correctly"
I got this method from the internet. Here is my SQL statement :
SELECT (
SELECT COUNT(*)
FROM Data_Kontrak
WHERE NOT (
(month(Tanggal_Berakhir_Izin)) <= month(now)
AND NOT (year(Tanggal_Berakhir_Izin)) <= year(now)
)
) AS Count1
,(
SELECT COUNT(*)
FROM Kontrak
WHERE NOT (
(month(Tanggal_Akhir)) <= month(now)
AND NOT (year(Tanggal_Akhir)) <= year(now)
)
) AS Count2
FROM dual

Related

SQL Question : Technical question that requires you to answer How many members worked at IBM before working at Google? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
Assume the following dataset:
member_id
company
Year_started
1
Apple
2001
1
IBM
2002
1
Oracle
2005
1
Microsoft
2010
2
IBM
2002
2
Microsoft
2004
2
Oracle
2008
Member 1, began work at IBM in 2002, moved to Oracle in 2005 and moved to Microsoft in 2010. Member 2, began workin gat IBM in 2002, moved to Microsoft in 2004 and then Moved to oracle in 2008. Assume that for each member in each year, there is only one company (cannot work at 2 different companies in the same year).
**Question: How many members ever worked at IBM prior to working at Oracle? **
How would you go about solving this? I tried a combination of CASE when's but am lost as to where else to go. Thanks.
...
..
I would phrase this using EXISTS:
SELECT DISTINCT member_id
FROM yourTable t1
WHERE company = 'Google' AND
EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.member_id = t1.member_id AND
t2.company = 'IBM' AND
t2.Year_started < t1.Year_started);
In plain English, the above query says to report every employee who worked at Google in some year, for which there is a record from an earlier year for the same employee who worked at IBM at that time.
I would go for querying the table twice and then join like so:
select count(*)
from (
select member_id, min(Year_started) y
from my_table
where company = 'IBM'
group by member_id
) i
join (
select member_id, max(Year_started) y
from my_table
where company = 'Oracle'
group by member_id
) o on i.member_id = o.member_id and i.y < o.y
Note the difference of min/max functions on the year column. This would yield a match for the use case Oracle-IBM-Oracle as well as IBM-Oracle-IBM.
Simply do a self join:
select count(distinct m1.member_id)
from members m1
join members m2
on m1.member_id = m2.member_id and m1.Year_started < m2.Year_started
where m1.company = 'IBM' and m2.company = 'Oracle';
More verbose, but using CTEs:
For each member_id, get the first year they worked at IBM (if any), and get the first year they worked at Oracle (again, if any).
"For each member_id" translates to GROUP BY member_id
"Get the first year..." translates to MIN( CASE WHEN "Company" = 'etc' THEN "Year_Started" END )
Filter those rows to rows where the first-year-at-IBM is less-than their first-year-at-Oracle.
Then simply get the COUNT(*) of those rows.
WITH ibmOracleYears AS (
SELECT
member_id,
MIN( CASE WHEN "Company" = 'IBM' THEN "Year_Started" END ) AS JoinedIbm,
MIN( CASE WHEN "Company" = 'Oracle' THEN "Year_Started" END ) AS JoinedOracle
FROM
yourTable
GROUP BY
member_id
),
workedAtIbmBeforeOracle AS (
SELECT
y.*
FROM
ibmOracleYears AS y
WHERE
y.JoinedIbm IS NOT NULL /* <-- This `IS NOT NULL` check isn't absolutely necessary, but I'm including it for clarity. */
AND
y.JoinedOracle IS NOT NULL
AND
y.JoinedIbm < y.JoinedOracle
)
SELECT
COUNT(*) AS "Number of members that worked at IBM before Oracle"
FROM
workedAtIbmBeforeOracle
But that query can be reduced down to this (if you don't mind anonymous expressions in HAVING clauses):
SELECT
COUNT(*) AS "Number of members that worked at IBM before Oracle"
FROM
(
SELECT
member_id
FROM
yourTable
GROUP BY
member_id
HAVING
MIN( CASE WHEN "Company" = 'IBM' THEN "Year_Started" END ) < MIN( CASE WHEN "Company" = 'Oracle' THEN "Year_Started" END )
) AS q
SQLFiddle of both examples.

How to return null values if there is no data to display in BigQuery [duplicate]

This question already has answers here:
Display default value if query results in no records in BigQuery
(2 answers)
Closed 10 months ago.
My question is I want to get null values when there is "no data to display" in the BigQuery.
like this:
But it only works when there are only aggregate functions. How to modify below query so that returns null values?
My query:
select oid, date, coalesce(sum(quantity_sold),0) as quantity_sold
from table
where oid = 'xxx' and (date >= 'xxx' and date <= 'xxx')
group by 1,2
I found this similar SO question but it creates a column that contains a message that says "Results not found" and assigns null values to other columns. You can apply this query and remove the message and retain only the null values, your query will look like this:
with sample_data as (
select 123 as oid, '2022-01-01' as date, 23 as quantity_sold
union all select 111 as oid, '2022-01-02' as date, 24 as quantity_sold
),
actual_query as (
select oid,date,coalesce(sum(quantity_sold),0) as quantity_sold
from sample_data
where oid = 534 and (date >= '2021-03-23' and date <= '2021-04-23')
group by 1,2
)
-- query below is the modified query from the linked SO question above
select actual_query.*
from actual_query
union all
select actual_query.* -- all the `actual_query` columns will be `NULL`
from (select 1) left join
actual_query
on 1 = 0 -- always false
where not exists (select 1 from actual_query);
Sample output:
NOTE: I created random values for sample data that could mimic the message "There is no data to display" when I ran your query.

AnalysisException: subqueries are not supported in the select list

I get this error code shown in title when using this following query. I'm trying query two tables to find total patients with hearing issues and the total of those patients with hearing issues who have undergone some sort of scan (MR,SC,CT).
SELECT (
SELECT COUNT(*)
FROM hearing_evaluation
where severity_of_hearing_loss <> 'Normal'
AND severity_of_hearing_loss <> 'insufficient data'
) AS patients_with_hearing_loss
, AVG(number_of_scans) AS avg_number_of_scans
FROM (
SELECT patient_id, COUNT(*) AS number_of_scans
from imaging
where patient_id IN (
SELECT patient_id
from hearing_evaluation
where severity_of_hearing_loss <> 'Normal'
and severity_of_hearing_loss <> 'insufficient data'
)
AND modality IN ('CT','MR','SC')
GROUP BY patient_id
) AS scans
Any help would be appreciated.
I tried, pls refer to below SQL - this will work in impala. Only issue i can see is, if hearing_evaluation has multiple patient ids for a given patient id, you need to de-duplicate the data.
There can be case when patient id doesnt exist in image table - in such case you need to apply RIGHT JOIN.
SELECT
COUNT(patient_id) AS patients_with_hearing_loss
, AVG(rs.number_of_scans) AS avg_number_of_scans
FROM (
SELECT i.patient_id patient_id, COUNT(*) AS number_of_scans
from imaging i ,hearing_evaluation h
where i. patient_id = h.patient_id
and h.severity_of_hearing_loss <> 'Normal'
and h.severity_of_hearing_loss <> 'insufficient data'
AND modality IN ('CT','MR','SC')
GROUP BY i.patient_id ) rs

Showing only max value of case statement in group by statement in SQL Server Management Studio

With a query I'd like to check for all the loans in our database, whether they main credit taker has an e-mail address filled out or not.
The problem I am encountering is that the Address table stores various types of addresses (also physical/fax addresses etc.). I can't simply filter on e-mail addresses as I would still like to see all loans (also those without e-mail), with the result whether or not they have an e-mail.
My current query still shows multiple rows for loans who have both mail and another form of address.
select l.ApplicationNumber, p1.Name AS Credittaker, a1.EAddress AS 'Mail
credit taker',
SUM(case
when c1.ContactChannelTypeID = 2 AND a1.ElectronicAddressTypeID = 1 then 1
else 0 end) as MailID
from Line l
JOIN Role r1 on (l.ObjID = r1.ObjID_Businessobject)
JOIN Party p1 on (p1.ObjID = r1.ObjID_Party)
JOIN ContactChannel c1 on (p1.ObjID = c1.ObjID_Party)
JOIN Address a1 on (a1.ObjID = c1.ObjID_Address)
WHERE r1.RDNameID = '17' AND r1.Enddate IS NULL AND c1.EndDate IS NULL
GROUP BY l.ApplicationNumber, p1.Name, a1.EAddress
order by l.ApplicationNumber
What I want is for the query to show 1 row per application number, if there is an e-mail (i.e. a row with MailID 1), to show only this value for the application number. If no e-mail is found (i.e. only row with MailID 0), to show this value.
How would I do this?
Example of results vs desired results:
11650 and 11651 only have non e-mail addresses so their value of MailID = 0 is correct. 11652 and 11653 both have an e-mail address and other types of addresses, and should therefore only display MailID = 1. Adding MAX(MailID) to the Group by clause doesn't work because it doesn't recognize the column name. If I put the case statement in a subquery and refer to it afterwards, I get the error that the an aggregate function can't contain another aggregate function.
I think this will work:
select top (1) with ties . . .
. . .
order by row_number() over (partition by l.ApplicationNumber order by MailId desc);
I'm not 100% sure you can use a column alias like this in the order by. If not, then :
with t as (
<your query here with no order by>
)
select
from (select t.*,
row_number() over (partition by applicationNumber order by mailid desc) as seqnum
from t
) t
where seqnum = 1;

Sum in subquery

My Query is
select count(*) as cnt,
EXTRACT(day FROM current_date - min(txdate))::int as days,
sum (Select opening from acledgerbal l
where acname='Arv'
union all
Select sum(v2.debit-v2.credit) as opening from acvoucher2 v2 where
txdate<='05/03/2014') as opening
from acduebills acb,acledger l
where (acb.opening+acb.debit-acb.credit) > 0
and acb.unitname='Sales'
and l.acname='Arv'
and l.acno=acb.acno
Here it show more than one row returned by a subquery used as an expression Error.
How do using sum for the subquery.
I'm using postgresql 9.1
EDIT:
I want to get count of rows in acduebills tables which is (acb.opening+acb.debit-acb.credit) > 0 and acb.unitname='Sales'. After that I want to get difference of day which is minimum date in same condition. After that I want to get opening, which comes from two tables: acledgerbal and acvoucher2. acvoucher is table checked by the txdate condition.
How to get those detail in single query?. How to get Same details in multiple schema's?
Something like this:
SELECT count(*) AS cnt
, current_date - min(txdate)::date AS days -- subtract dates directly
, (SELECT round(sum(opening)::numeric, 2)
FROM (
SELECT opening
FROM acledgerbal
WHERE acname = 'Arv'
UNION ALL
SELECT debit - credit
FROM acvoucher2
WHERE txdate <= '2014-05-03'
) sub
) AS opening
FROM acduebills b
JOIN acledger l USING (acno)
WHERE ((b.opening + b.debit) - b.credit) > 0
AND b.unitname ='Sales'
AND l.acname = 'Arv';
round() to decimal places only works with type numeric, so I cast the sum.
The problem here in the following statement:
sum ( Select opening from acledgerbal l
where acname='Arv'
union all
Select sum(v2.debit-v2.credit) as opening from acvoucher2 v2,
txdate<='05/03/2014' )
You use UNION so this subquery returns at least 2 rows. So you get an error that subquery can't return more than one row: "more than one row returned by a subquery used as an expression"
Try to change it to:
(Select SUM(opening) from acledgerbal l WHERE acname='Arv')
+
(Select SUM(v2.debit-v2.credit) as opening from acvoucher2 v2
WHERE txdate<='05/03/2014')