How can i divide two expressions in Microsoft SQL Server - sql

How can i divide two expressions in Microsoft SQL Server which give Numbers as a Result? I tried with a /, but this didn't work
SELECT COUNT(*) FROM A
SELECT COUNT(*) FROM B WHERE c = 1
I tried with / but this didnt work
SELECT COUNT(*)
FROM A/SELECT COUNT(*) FROM B WHERE c = 1

It might depend on RDBMS, this works in sql server.
SELECT ACounts/ CAST(BCounts AS Decimal(29,20))
FROM (SELECT COUNT(*) AS ACounts FROM A) AS suba
, (SELECT COUNT(*) AS BCounts FROM B WHERE c = 1) AS subb
Note that I cast the BCounts to a decimal of arbitrary size otherwise it will round off to the nearest whole number. Ignore that part if that is what you wanted.
This also works
SELECT (SELECT COUNT(*) AS ACounts FROM A)/ CAST((SELECT COUNT(*) AS BCounts FROM B WHERE c = 1) AS Decimal(29,20))

Use subqueries:
SELECT (a.countA / b.countB) As divisionResult
FROM
(SELECT COUNT(*) AS countA FROM A) a,
(SELECT COUNT(*) AS countB FROM B WHERE c = 1) b
;

Related

Trying to divide two counts in SQL

so I'm trying to do simple division and of course SQL, being super logical that it is, makes it impossible. What I am trying to do is this:
SELECT * FROM
1 - ((SELECT COUNT(DISTINCT T.DID) FROM TGAMAZING T AS NUM) * 100 /
(SELECT COUNT(DISTINCT D.ID) FROM DIRECTORS D AS DENOM))
but how would I write this SQL (Oracle)?
Oracle
SQL Fiddle: http://sqlfiddle.com/#!4/34298/8
Method 1:
SELECT 1 - (COUNT(DISTINCT DID) * 100 / COUNT(DISTINCT ID))
FROM TGAMAZING
cross join DIRECTORS;
Method 2:
SELECT 1 -
(
(SELECT COUNT(DISTINCT DID) FROM TGAMAZING) * 100 /
(SELECT COUNT(DISTINCT ID) FROM DIRECTORS)
)
FROM DUAL;
SQL Server
SQL Fiddle: http://sqlfiddle.com/#!6/34298/3
Method 1
SELECT 1 - (COUNT(DISTINCT DID) * 100.0 / COUNT(DISTINCT ID))
FROM TGAMAZING
cross join DIRECTORS;
Method 2
SELECT 1 -
(
(SELECT COUNT(DISTINCT DID) FROM TGAMAZING) * 100.0 /
(SELECT COUNT(DISTINCT ID) FROM DIRECTORS)
)
Write the calculation as it were fields and use "FROM DUAL", as you don't want to query any of your tables.
SELECT
1 - ((SELECT COUNT(DISTINCT T.DID) FROM TGAMAZING T) * 100 /
(SELECT COUNT(DISTINCT D.ID) FROM DIRECTORS D))
AS RESULT
FROM DUAL
Reference: Selecting from the DUAL Table.

How can I get the count of multiple columns in SQL

Say I had two tables in SQL. Now I would like to get the quotient of the count of table 1 and count of table 2. How can I do that?
In Short:
(# of rows in table 1) / (# of rows in table 2)
EDIT:
This is what I tried:
SELECT COUNT(t1.a) / COUNT(t2.a)
FROM table1 t1, table2 t2
Here's one way to get the result:
SELECT c1.cnt / c2.cnt AS q
FROM ( SELECT COUNT(1) AS cnt
FROM table1
) c1
CROSS
JOIN ( SELECT COUNT(1) AS cnt
FROM table2
) c2
Another way to get an equivalent result:
SELECT (SELECT COUNT(1) FROM table1) / (SELECT COUNT(1) FROM table2) AS q
I would prefer the first query if I also needed to return the counts from the tables as separate columns in the resultset, for example:
SELECT c1.cnt AS table1_count
, c2.cnt AS table2_count
, c1.cnt / c2.cnt AS q
FROM ...
Try this:
SELECT COUNT(table1.column) as 'Table 1 Count'
,COUNT(table2.column) as 'Table 2 Count'
,COUNT(table1.column) / COUNT(table2.column) as 'Quotient'
FROM table1, table2
with
Ctable1 as
(select count(*) as num1 from table1),
Ctable2 as
(select count(*) as num2 from table2)
select num1 / num2 as quotient
from Ctable1,Ctable2
Remember:
When you count column, rows with "NULL" data will NOT count. (If you use Oracle, you can use count(a.*)
Int division in sql like most languages, returns int. (5/2 = 2 and not 2.5).

Pattern matching SQL on first 5 characters

I'm thinking about a SQL query that returns me all entries from a column whose first 5 characters match. Any ideas?
I'm thinking about entries where ANY first 5 characters match, not specific ones. E.g.
HelloA
HelloB
ThereC
ThereD
Something
would return the first four entries:
HelloA
HelloB
ThereC
ThereD
EDIT: I am using SQL92 so cannot use the left command!
Try this :
SELECT *
FROM YourTable
WHERE LEFT(stringColumn, 5) IN (
SELECT LEFT(stringColumn, 5)
FROM YOURTABLE
GROUP BY LEFT(stringColumn, 5)
HAVING COUNT(*) > 1
)
SQLFIDDLE DEMO
This selects the first 5 characters, groups by them and returns only the ones that happen more than once.
Or with Substring:
SELECT * FROM YourTable
WHERE substring(stringColumn,1,5) IN (
SELECT substring(stringColumn,1,5)
FROM YOURTABLE
GROUP BY substring(stringColumn,1,5)
HAVING COUNT(*) > 1)
;
SQLFIDDLE DEMO
Sounds easy enough...
In SQL Server this would be something along the lines of
where Left(ColumnName,5) = '12345'
Try
Select *
From tbl t1
Where exists (
Select 1
From tbl t2
Where left(t1.str, 5) = left(t2.str)
Group by left(t2.str, 5)
Having count(1) > 1
)
You didn't specify your DBMS. If it supports Windowed Aggregate functions it's:
select *
from
(
select
tab.*,
count(*) over (partition by substring(col from 1 for 5) as cnt
from tab
) as dt
where cnt > 1
You want to work with a CTE approach.
Something like this:
with CountriesCTE(Id, Name)
as (
select Id, Name from Countries
)
select distinct Countries.Name
from CountriesCTE, Countries
where left(CountriesCTE.Name,5) = left(Countries.Name,5) and CountriesCTE.Id <> Countries.Id

SELECT on two other queries in Oracle

So, lets say I want to do something like:
SELECT Query1.a,
Query2.b
FROM (
SELECT q as a
FROM somewhere
),
(
SELECT g as b
FROM elsewhere
)
where Query 1 is
(
SELECT q as a
FROM somewhere
)
and Query2 is
(
SELECT g as b
FROM elsewhere
)
So, i want to select from two other select statements.
Query 1 produces a table
a
value1
Query 2 produces a table
b
value 2
And Query 3 (the outer select statement) produces
a b
value 1 value 2
So, essentially, two result tables are combined as columns and not as rows.
Thank you, if you have any hints.
You basically have your solution. You are only missing the names of your queries, so do like this:
SELECT Query1.a,
Query2.b
FROM (
SELECT q as a
FROM somewhere
) Query1,
(
SELECT g as b
FROM elsewhere
) Query2
It's not clear how you need to connect different rows from tables but it can be something like this:
select query1.a,
query2.b
FROM
(select q as a, ROW_NUMBER() OVER (ORDER BY q) as RN from a) Query1
FULL JOIN
(select q as b, ROW_NUMBER() OVER (ORDER BY q) as RN from b) Query2
ON Query1.RN=Query2.RN
SQLFiddle example
Your syntax is a bit off the SQL charts, but in essence ritgh:
It is possible to do a subquery:
select A.field from (select field from a_table) A;
It is essential that you name your query, if you want to use it in the select or where clauses.
And even possible to combine them like regular tables:
select A.field, B.other_field from (select field from table1) A, (select other_field from table2) B;
It is also possible to do al kind of where, grouping and sorting stuff on it, but not needed in your case.
I assume this is what you're looking for:
SELECT query1.a, query2.b
FROM
(SELECT q as a FROM somewhere) query1,
(SELECT g as b FROM elsewhere) query2
Here is a SQLFiddle to test the query

How to get Original Rows filtered by a HAVING Condition?

What is the method in T-SQL to select the orginal values limited by a HAVING attribute. For example, if I have
A|B
10|1
11|2
10|3
How would I get all the values of B (Not An Average or some other summary stat), Grouped by A, having a Count (Occurrences of A) greater than or equal two 2?
Actually, you have several options to choose from
1. You could make a subquery out of your original having statement and join it back to your table
SELECT *
FROM YourTable yt
INNER JOIN (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
) cnt ON cnt.A = yt.A
2. another equivalent solution would be to use a WITH clause
;WITH cnt AS (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
)
SELECT *
FROM YourTable yt
INNER JOIN cnt ON cnt.A = yt.A
3. or you could use an IN statement
SELECT *
FROM YourTable yt
WHERE A IN (SELECT A FROM YourTable GROUP BY A HAVING COUNT(*) >= 2)
A self join will work:
select B
from table
join(
select A
from table
group by 1
having count(1)>1
)s
using(A);
You can use window function (no joins, only one table scan):
select * from (
select *, cnt=count(*) over(partiton by A) from table
) as a
where cnt >= 2