Select all data with same ID in a table - sql

I just want to know the correct syntax because what I've done is not what I wanted. So here is the sample table on database,
|ID |BOOKS |COURSE
+------+--------+------+
|1 |web book| A |
|1 |java | A |
|2 |php | B |
|2 |html | B |
In my UI, I have this table. I have a button in the column of the table that will trigger a modal to show the borrowed books of the student in that row.
|ID |COURSE|ACTION|
+------+------+------+
|1 |A |SHOW |
|2 |B |SHOW |
Whenever I want to show the borrowed book of ID = 1, the output on modals should be like
|BOOKS |
+--------+
|web book|
|java |
because that's what ID=1 borrowed. Thanks in advance.
My current query:
SELECT book
FROM borrowing_tbl
where ID in (SELECT ID
FROM borrowing_tbl
GROUP BY ID
HAVING COUNT(*) > 1)
it keeps showing all data with duplicated ID

Select all books with ID 1
Select ID
From BOOKS
Where BOOKS.ID = 1
I'm sure you could lay your tables out better
Edit:
SELECT BOOKS.name
FROM BOOKS
JOIN students on students.id = BOOKS.id
WHERE students.courses = 'A';

Related

Returning rows that contain text from another table

I have two tables Main and Lookup
Main has a column called [Promotion Codes List] that is a string of different promo codes comma separated.
Lookup has a column of all the individual promotion codes called [Promotion Codes].
I am trying to create a view of the Main table that will filter Main table if if Main.[Promotion Codes List] contains a code that is in the Lookup.[Promotion Codes] table.
Main Table sample data
|id|Promotion Codes List|
|--| ------------------ |
|1 | BR-Coll-210731-10903, BR-NFRD-210731-10124 |
|2 | BR-Coll-210731-10903, BR-Deal-210731-11265 |
|3 | BR-Coll-210731-11037, BR-Deal-210731-11275 |
|4 | BR-Coll-210731-11037 |
Lookup Table sample data
|id|Promotion Codes|
|--| ------------- |
|1 | BR-NFRI-251231-04855 |
|2 | BR-Deal-210731-11265 |
|3 | BR-Coll-210731-11402 |
|4 | BR-Deal-210731-11275 |
|5 | BR-Coll-210731-11037 |
Desired output
Main Table
|id|Promotion Codes List|
|--| ------------------ |
|2 | BR-Coll-210731-10903, BR-Deal-210731-11265 |
|3 | BR-Coll-210731-11037, BR-Deal-210731-11275 |
|4 | BR-Coll-210731-11037 |
I started off playing around with
SELECT Promotion Codes List, CASE WHEN EXISTS (SELECT *
FROM dbo.[Lookup] B
WHERE B.[Promotion Codes] = A.Promotion Codes List) THEN 'common' ELSE 'not common' END AS valid FROM dbo.Main AS A
and it works if there is are exact matches in row, but as you can see in the main table there can be multiple br codes in one record so I tried to add a like statement somewhere but couldn't figure it out.
Thanks !
Try below
SELECT Promotion Codes List, CASE WHEN EXISTS (SELECT 1
FROM dbo.[Lookup] B
WHERE A.[Promotion Codes List] like '%'+B.[Promotion Codes]+'%') THEN 'common' ELSE 'not common' END AS valid FROM dbo.Main AS A

How can I count occasions of grouped values in a table?

I have the table in my postgres db below. I would like to know how many times the the values (name1, name2, name3) occur in the table where trial is 1.
In the case below the expected output:
name1, 4
name2, 3
name3, 2
+--------------+
| id|name|trial|
+--------------+
|1 |name1|1 |
|2 |name1|1 |
|3 |name1|1 |
|4 |name1|1 |
|5 |name2|1 |
|6 |name2|1 |
|7 |name2|1 |
|8 |name3|1 |
|9 |name3|1 |
What I tried so far:
SELECT count(C.NAME)
FROM FIRST AS C
WHERE NAME = (
SELECT CS.NAME
FROM FIRST AS CS
WHERE TRIAL = 1
GROUP BY CS.NAME
)
this query returns with 9, which is number of rows.
You're missing the group by clause. Also, the query can be simplified, try this:
SELECT count(1), Name
FROM FIRST
WHERE TRIAL = 1
GROUP BY Name

SQL Insert Query For Multiple Max IDs

Table w:
|ID|Comment|SeqID|
|1 |bajg | 1 |
|1 |2423 | 2 |
|2 |ref | 1 |
|2 |comment| 2 |
|2 |juk | 3 |
|3 |efef | 1 |
|4 | hy | 1 |
|4 | 6u | 2 |
How do I insert a standard new comment for each ID for a new SeqID (SeqID increase by 1)
The Below query results in the highest SeqID:
Select *
From w
Where SEQID =
(select max(seqid)
from w)
Table w:
|2 |juk | 3 |
Expected Result
Table w:
|ID|Comment|SeqID|
|1 |sqc | 3 |
|2 |sqc | 4 |
|3 |sqc | 2 |
|4 |sqc | 3 |
Will I have to go through and insert all the values (new comment as sqc) I want into the table using the below, or is there a faster way?
INSERT INTO table_name
VALUES (value1,value2,value3,...);
Try this:
INSERT INTO mytable (ID, Comment, SeqID)
SELECT ID, 'sqc', MAX(SeqID) + 1
FROM mytable
GROUP BY ID
Demo here
You are probably better off just calculating the value when you query. Define an identity column on the table, say CommentId and run a query like:
select id, comment,
row_number() over (partition by comment order by CommentId) as SeqId
from t;
What is nice about this approach is that the ids are always sequential, you don't have no opportunities for duplicates, the table does not have to be locked to when inserting, and the sequential ids work even for updates and deletes.

Column 'Course.Course_Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I need to link two tables columns, please help me. This my code:
SELECT Student.Stu_Course_ID, Course.Course_Name, COUNT(Student.Stu_ID) AS NoOfStudent FROM Student
INNER JOIN Course
ON Student.Stu_Course_ID=Course.Course_ID
GROUP BY Stu_Course_ID;
This is my course table:
__________________________________________
|Course_ID | Course_Name |
|1 | B.Eng in Software Engineering |
|2 | M.Eng in Software Engineering |
|3 | BSC in Business IT |
I got number of students from student table
_____________________________
|Stu_Course_ID | NoOfStudents |
|1 | 30 |
|2 | 12 |
|3 | 20 |
This is what i want
____________________________________________________________
|Stu_Course_ID | Course_Name | NoOfStudents|
|1 | B.Eng in Software Engineering | 30 |
|2 | M.Eng in Software Engineering | 12 |
|3 | BSC in Business IT | 20 |
You need to add Course.Course_Name to your group by clause:
SELECT Student.Stu_Course_ID,
Course.Course_Name,
COUNT(Student.Stu_ID) AS NoOfStudent
FROM Student
INNER JOIN Course
ON Student.Stu_Course_ID=Course.Course_ID
GROUP BY Student.Stu_Course_ID, Course.Course_Name;
Imagine the following simple table (T):
ID | Column1 | Column2 |
----|---------+----------|
1 | A | X |
2 | A | Y |
Your query is similary to this:
SELECT ID, Column1, COUNT(*) AS Count
FROM T
GROUP BY Column1;
So, you know you have 2 records for A in column1, so you expect a count of 2, however, you are also selecting ID, there are two different values for ID where Column1 = A, so the following result:
ID | Column1 | Count |
----|---------+----------|
1 | A | 2 |
Is no more or less correct than
ID | Column1 | Count |
----|---------+----------|
2 | A | 2 |
This is why ID cannot be contained in the select list, unless it included in the group by clause, or as part of an aggregate function.
For what it's worth, if Course_ID is the primary key in the table Course then following query is legal according to the SQL Standard, and will work in Postgresql, and I suspect at some point Microsoft will build this functionality into SQL Server too:
SELECT Course.Course_ID,
Course.Course_Name,
COUNT(Student.Stu_ID) AS NoOfStudent
FROM Student
INNER JOIN Course
ON Student.Stu_Course_ID=Course.Course_ID
GROUP BY Course.Course_ID;
The reason for this is that since Course.Course_ID is the primary key of Course there can be no duplicates of this in the table, therefore there can only be one value for Course_name for each Course_ID
give columns names after group by statements which you want to retreive so you have to also give Course.Course_Name as well...

SQL Group by one column, count entries in another

I'm using a sqlite3 database, with a table like this.
|name |action |
-------------------------
|john |run |
|jim |run |
|john |run |
|john |jump |
|jim |jump |
|jim |jump |
|jim |dive |
I want to get an output like this
|name |run |jump |dive |
---------------------------------
|john |2 |1 |0 |
|jim |1 |2 |1 |
The closest I've come is with this, but I would like to have a single row like above.
SELECT name, action, COUNT(name)
FROM table
GROUP BY name, action
|name |action |COUNT(name) |
|john |run |2 |
|john |jump |1 |
|jim |run |1 |
|jim |jump |2 |
|jim |dive |1 |
Also, I will need to have some WHERE statements in the query as well.
Am I up in the night thinking this will work?
You can also accomplish what you want by using a sum aggregate and CASE conditions like this:
SELECT name,
sum(CASE WHEN action = 'run' THEN 1 END) as run,
sum(CASE WHEN action = 'jump' THEN 1 END) as jump,
sum(CASE WHEN action = 'dive' THEN 1 END) as dive
FROM table
GROUP BY name
You will still have to change the query every time additional actions are added.
What you are trying to do is called cross tabulation. Normally this is available as a feature called pivot table in Excel and other spreadsheet softwares.
I have found a blog article which will help you with this using SQL. Check out pivot-table-hack-in-sqlite3-and-mysql
I don't know SQLLite that well, but I image that you could use subqueries or temp tables.
With mssql you could write something like this:
select Name,
(select count(*) from table as t1 where t1.Name = table.Name and t1.Action = 'run') as Run,
(select count(*) from table as t1 where t1.Name = table.Name and t1.Action = 'dive') as dive,
(select count(*) from table as t1 where t1.Name = table.Name and t1.Action = 'jump') as run
from table
But this would need to be rewritten every time you ad another action type. You should probably add an index to get the speed up on the table. But check the query plan with "real" data first.
in oracle database you can write like below query to show required solution :-
select * from table_name
pivot (count(*) for action in ('run','jump','drive'))
this will give the desired output..