Selecting unique value SQL - sql

When running this SQL query it returns each Find_ID four times, how can I make it only select unique finds?
SELECT A.FIND_ID, B.NAME, PERIOD
FROM FINDS A, CLASS B
WHERE A.X >= 4
AND A.X <= 10
AND A.Y >= 4
AND A.Y <= 10
AND FIND_ID = DISTINCT
This returns
FIND_ID NAME PERIOD
========== ==================== ====================
2 SHARD BRONZE
5 SHARD BRONZE
2 METAL_WORK IRON_AGE
5 METAL_WORK IRON_AGE
2 FLINT MESOLITHIC
5 FLINT MESOLITHIC
2 BONE RECENT
5 BONE RECENT

Use the distinct property.. Select Distinct(SAMPLE) From table1

If the two tables FINDS and CLASS are related you need to be using some kind of join (INNER, at a guess). The reason why you are getting four results is that you are running a query that returns the cartesian product of your results - that is, you will get all combinations of both tables joined together without a common field linking the two of them together.
Here's an example. Let's say you have the two really simple tables below:-
PersonID Name
1 Matt
2 Fred
PersonID Salary
1 23000
2 18000
Then a query like:-
SELECT * FROM Person, Salary
Would return something like:-
PersonID Name PersonID Salary
1 Matt 1 23000
2 Fred 2 18000
1 Matt 2 18000
2 Fred 1 23000
Et voila, four records where you might expect two. Adding DISTINCT to this would achieve nothing, as each of the rows is distinct. To link the related tables you would need something like:-
SELECT * FROM Person INNER JOIN Salary ON Person.PersonID = Salary.PersonID

Related

Translate sql query on Django

I have two tables: students (that has all the students of a school) and suspensions (all the students that are suspended)
id
name
school_grade
1
Jeff
1
2
Dave
1
3
Susan
2
4
Will
2
5
Peter
3
id
reason
student_id
1
Missed class
1
2
Arrived 20 times late
2
3
Fight
5
So I need to get statistics of which students of different grades are suspended.
So, my query is this.
SELECT school_grade, count(school_grade)
FROM students JOIN suspensions ON students.id=suspensions.student_id
GROUP BY school_grade;
And this query gives me exactly what I want.
school_grade
number of suspension
3
1
1
2
But I don't understand how to make this query on django.
Try:
students.objects.values("school_grade").annotate(Count("suspensions"))
This should work as expected

How to count entries in sql "like in a loop"

First thing, I'm very new to databases so this is probably a very simple question, but I didn't know how to google it or how to give it a good title. I'm using postgres from python, but the problem is to put together the right query.
The scenario is the following. I hava a table with columns: ID, Trial, Subject, Invalid. It comes from a behavioral experiment where many subjects perform a task that is composed of several trials. Their responses can be invalid for different reasons, and depending on the reason there is a different invalidation code (an integer). A valid response has code 0.
------------------------------
ID | SUBJECT | TRIAL | INVALID
------------------------------
1 Peter 1 0
2 Peter 2 0
3 Peter 3 1
4 Peter 4 3
5 Mary 1 3
6 Mary 2 2
7 Mary 3 0
8 Mary 4 2
I would like to do two things (which I'm not sure how to do in an elegant way).
a) For each subject, I would like to know how many responses are in total and how many are valid. Now I'm making a query for each subjects, with the condition, e.g., WHERE Subject='Peter', but I can imagine that there is a more elegant solution.
Sample answer:
Subject Valids Total
Peter 2 4
Mary 1 4
b) For each subjects, I would like to know how many responses were invalid for each of the invalidation codes. Ideally I would get a table like:
Subject Invalid Count
Peter 0 2
Peter 1 1
Peter 2 0
Peter 3 1
Mary 0 1
Mary 1 0
Mary 2 2
Mary 3 1
Query #1: You want one result row per subject, so you group by subject. Use COUNT to count all records for a subject and COUNT in combination with CASE to count conditionally (all valid ones).
select
subject,
count(*) as all_responses,
count(case when invalid = 0 then 1 end) as valid_responses
from mytable
group by subject;
Query #2: Here you want one result row per subject and code, so you group by these two. Then count with COUNT.
select
subject,
invalid,
count(*) as responses
from mytable
group by subject, invalid;
UPDATE: In your updated request you want query #2 to show all subject/code combinations even if they have a count of 0. In order to do this, you'd have to create the set of all valid combinations first and then outer join your response table:
select
s.subject,
c.code,
count(m.invalid) as responses
from subjects s
cross join codes c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;
If you don't have tables for subjects and code (which you should), you can get them from your responses table instead:
select
s.subject,
c.code,
count(m.invalid) as responses
from (select distinct subject from mytable) s
cross join (select distinct invalid as code from mytable) c
left join mytable m on (m.subject = subjects.subject and m.invalid = codes.code)
group by s.subject, c.code;

Splitting the data through SSIS

I have a table "Employee" as shown below
Id Name
1 John
2 Jaffer
3 Syam
4 Aish
5 Gidson
1 Aboo
2 Sindhu
3 Saravanan
I want to get two outputs like
Id
1
2
3
Id
4
5
Which transformation should i use?
Could you Please help on that?
You will have to write two queries.
SELECT Id
FROM Employee
GROUP BY Id
HAVING COUNT(Id)>1
The above query will give you first output
SELECT Id
FROM Employee
GROUP BY Id
HAVING COUNT(Id)=1
This will give you 2nd output.

Efficient ways to count the number of times two items are ordered together

I am currently stuck on a problem where I have to write a SQL query to count the number of times a pair of items is ordered together.
The table that I have at my disposal is something like:
ORDER_ID | PRODUCT_ID | QUANTITY
1 1 10
1 2 20
1 3 10
2 1 10
2 2 20
3 3 50
4 2 10
I am looking to write a SQL query that can, for every unique pair of items, count the number of times they were ordered together and tell me the quantities when they were in the same order.
The resulting table should look like:
PRODUCT_ID_1 | PRODUCT_ID_2 | NUM_JOINT_ORDERS | SUM_QUANTITY_1 | SUM_QUANTITY__2
1 2 2 20 40
1 3 1 10 10
2 3 1 20 10
Some things to exploit are that:
Some orders only contain 1 item and so are not relevant in counting the pairwise relationship (not sure how to exclude these but maybe it makes sense to filter them first)
We only need to list the pairwise relationship once in the final table (so maybe a WHERE PRODUCT_ID_1 < PRODUCT_ID_2)
There is a similar post here, though I have reposted the question because
I really want to know the fastest way to do this since my original table is huge and my computational resources are limited, and
in this case I only have a single table and no table that lists the number.
You may use the following approach, which gives you the result shown above.
select
PRODUCT1, PRODUCT2, count(*), sum(QUANTITY1), sum(QUANTITY2)
from (
select
T1.PRODUCT_ID AS PRODUCT1,
T2.PRODUCT_ID AS PRODUCT2,
T1.QUANTITY AS QUANTITY1,
T2.QUANTITY AS QUANTITY2
from TABLE as T1, TABLE as T2
where T1.ORDER_ID=T2.ORDER_ID
and T1.PRODUCT_ID<T2.PRODUCT_ID
)
group by PRODUCT1, PRODUCT2

How to get all the records from the Table A and only common records from table B in sql

I have two tables Table A and Table B as follows.
TableA:
Id name
1 abc
2 john
3 jack
4 jill
Table B:
Id city phn
1 london 9876345
5 bangalore 2345678
3 chennai 5637473
I want records which are present in tableA but not in Table B.But the result should be
TableA:
Id name
1 abc
2 john
3 jack
4 jill
i.e even though 1 and 3 ids are present in Table B but they are still in table A.I want those records too.
5 bangalore 2345678
this records is not present in Table A.so i should not take this.
Really -- this simple? Don't think you need any joins then...
SELECT * FROM TableA
Good luck.
You need a left outer join.
Look into it here: http://en.wikipedia.org/wiki/Join_(SQL) and here: http://www.w3schools.com/sql/sql_join_left.asp
EDIT:
Your question makes no sense to be honest. In the heading you mention: "All the values in A and only common values in B" and then, you go on to state in the explanation that you need values from 'A' only and not B.. for that
select * from TableA will do.