Complicated query in mysql database - java

I have two Tables:
**user**
idU - autoincrement
name
**automobile**
idA - autoincrement
id_user
value
date - type: yyyy-mm-dd
Each user has many automobile
A automobile has only one user
Currently i am using the following query for all users(5 in total):
select sum(value) as user_value, name
from user inner join automobile on user.idU = automobile.id_user
where name like ? AND date = ?
what i want? I want the total value of all user in specific date using 1 query. how can i do this?
#edit1:
TABLE USER
--idU------name----
1 mateus
2 joao
3 maria
TABLE AUTOMOBILE
--idA---id_user----value-------date------
1 1 250 2013-10-13
2 3 322 2013-10-13
3 1 150 2013-10-13
4 3 80 2013-10-13
5 2 100 2013-11-13
6 3 500 2013-11-13
7 1 1100 2013-11-13
8 1 50 2013-12-13
9 3 135 2013-12-13
10 2 40 2013-12-13
I request a query with date = 2013-10-13 and it return:
---name---value
mateus 400
maria 422

Something like:
select sum(value) as user_value,
name inner join automobile on user.idU = automobile.id_user
where date = ?
group by user.idU
-----------EDIT------------
select name, sum(value) as value
from user inner join automobile on user.idU = automobile.id_user
where date = "2013-10-13"
group by automobile.id_user
SQLFiddle here: http://sqlfiddle.com/#!2/8115c/4

Assuming you're wanting a list of each user with the total value of their automobiles with a particular date, you'll need to group by any user fields which you're selecting:
SELECT
SUM(a.value) as user_value,
u.name
FROM
user u INNER JOIN
automobile a on u.idU = a.id_user
WHERE
a.date = ?
GROUP BY
u.name

I am not entirely sure if I got it right. Since you're using aggregate function ('sum') it would normally return only one row containing sum of the values. But if you'd like to execute the query anyway, maybe this would help (not tested)..
UPDATED
SELECT
SUM(automobile.value) as totalValue,
user.name
FROM
automobile
INNER JOIN
user
ON automobile.id_user = user.idu
WHERE
automobile.date between '2013-10-13' and '2013-10-13'
GROUP BY
automobile.id_user

Related

How to Query three (3) tables having one Identical field in all and Group the result by another field?

I'm performing an analysis on a certain warehouse within a java program using SQL as its database.
I have 3 tables; table1 contains the general details of a products, table2 contains the transaction details of the product in one region i.e. Region A and table 3 contains transaction details of the product in the other region, say Region B.
Table1 - General Details
id itemID itemName Qty category
1 TAG01 Acer Laptops 10 Electronics
2 TAG04 Baking Floor 200 Foods
3 TAG08 Philips Bulbs 700 Electronics
4 TAG109 Sweat Pants 85 Wear
Table2 - details from Region A
id itemID sellDate
1 TAG01 "
2 TAG01 "
3 TAG109 "
4 TAG01 "
Table3 - details from Region B
id itemID sellDate
1 TAG109 "
2 TAG109 "
I want to select category with its Total Qty from Table1 and attach to it the total number of counts of the distinct itemID from Table2 and Table3
Expect results:
id category Qty totalTransactions
1 Electronics 710 3
2 Foods 200sacks -
3 Wear 85 3
This is what I tried and it give satisfying results
String sql = "SELECT category, Qty FROM table1 INNER JOIN (SELECT itemID, COUNT(*) FROM (SELECT itemID FROM table3 union ALL SELECT itemID FROM table2)t GROUP BY itemID)q"
This should give you what you need. I am joining against two sub-queries where each query performs a COUNT per itemId and then the SUM of the two is done in the main query plus the SUM of the Qty column.
LEFT JOIN is used since not all rows in table1 might have rows in the transaction tables.
SELECT category, SUM(Qty), SUM(IFNULL(t3.c3,0) + IFNULL(t2.c2, 0))
FROM table1 t1
LEFT JOIN (SELECT itemId, COUNT(*) c2 FROM table2 GROUP BY itemId) t2 ON t2.itemId = t1.itemID
LEFT JOIN (SELECT itemId, COUNT(*) c3 FROM table3 GROUP BY itemId) t3 ON t3.itemId = t1.itemID
GROUP BY category

SQL: Get a limit of records per entity

I have the following setup (Java/Hibernate/PostgreSQL):
TeamName {
id: Long;
name: String;
team: Team;
....
}
Series {
id: Long;
season: Season;
dateScheduled: Date;
}
SeriesTeam {
id: Long;
series: Series;
team: TeamName;
}
SeriesTeam {
id: Long;
team: TeamName;
}
What I want to do is do a select of the past n series (say 10) or the next series from the current date. Here's what I have so far:
select s.* from series s
inner join series_teams st on st.series_id = s.id
inner join team_names tn on tn.id = st.team_name_id
where tn.id in (:teamIds) and s.date_scheduled < CURRENT_DATE
order by s.date_scheduled desc
But that is going to get me all the prior series for all teams and I will have to use Java to pick out what I want How would I go about doing what I want? Thanks!
EDIT: For example, say I wanted a limit of 10 per team name, and there are 24 teams, I would want max of 240 records returned to me. (assuming 10 exist before current date)
EDIT2: Here is the code that I want for a single team:
select s. from series s
inner join series_teams st on st.series_id = s.id
where st.team_name_id=85 and s.date_scheduled < CURRENT_DATE
order by s.date_scheduled desc
limit 10
I just need to be able to apply this for all the teams....I don't want to make x SQL calls for every team.
I think this will work. The syntax is in mysql and you can try it at that site the structure they have is similar to yours. you can adjust the limit value to change how many from each employee to return sorted by date. Probably add the current date check there too i guess.
Basically I joined all the needed tables together then created a new column that will tell me if that row is one we should return then added that check in the where clause.
https://www.w3schools.com/sql/trysql.asp?filename=trysql_op_in
SELECT e.employeeid, lastname,orderdate, orderdate in (select orderdate from
orders ord where e.employeeid=ord.employeeid order by orderdate limit 2) as
good FROM Employees as e join orders as o on e.employeeid=o.employeeid where
good=1 order by e.employeeid, o.orderdate;
for your case:
select s.id, s.season_id, s.date_scheduled, st.team_name_id,
s.date_scheduled in (
select s2.date_scheduled from series s2
inner join series_teams st2 on st2.series_id = s2.id
inner join team_names tn2 on tn2.id = st2.team_name_id
where tn.id =tn2.id and s2.date_scheduled < CURRENT_DATE
order by s.date_scheduled desc limit 5
) as foo
from series s
inner join series_teams st on st.series_id = s.id
inner join team_names tn on tn.id = st.team_name_id
where tn.id in (:teamIds) and foo = true
order by st.team_name_id, s.date_scheduled desc

Dynamic attribute name search

Consider I have a student table like this:
student_id name address ... school employer
1 Chris 2 John UofJ J Limited
2 Ann 3 Doe UofD D limited
Right now I need to find a list of students who have school = 'UofJ' and employer = 'J Limited'. Easy:
select * from student where school = 'UofJ' and employer = 'J Limited'
However, my reality is the last 2 attributes are stored in student table as columns but in a separate table called student_attribute as rows:
student_attribute_id student_id attribute_name attribute_value
1 1 school UofJ
1 1 company J Limited
1 2 school UofD
1 2 company D Limited
My task is to find a list of student IDs from this student_attribute table still based on school = 'UofJ' and employer = 'J Limited'. How should I do it?
Moreover, I am using Springboot JPS repository to do the query, so I am willing to listen to solution to both a sql way or JPA way.
You can use conditional aggregation to find out which student_id has both the conditions true.
select student_id
from student_attribute
group by student_id
having count(case
when attribute_name = 'school'
and attribute_value = 'UofJ'
then 1
end) > 0
and count(case
when attribute_name = 'company'
and attribute_value = 'J Limited'
then 1
end) > 0
You can then maybe join it with the student table to get the corresponding details.
select s.*
from student s
join (
select student_id
from student_attribute
group by student_id
having count(case
when attribute_name = 'school'
and attribute_value = 'UofJ'
then 1
end) > 0
and count(case
when attribute_name = 'company'
and attribute_value = 'J Limited'
then 1
end) > 0
) a on s.student_id = a.student_id;
Set up a join for each attribute you care about:
select * from student s
join student_attribute school on school.student_id = s.student_id
join student_attribute company on company.student_id = s.student_id
where company.attribute_value='J Limited'
and school.attribute_value='UofJ'

How implement friends Relationship android

I'm trying to implement some code for get friends list.
First:
- I have my String id. E.G: 784717
- I have an string with 100 numbers. E.G: 7781,5913,551949194,4919491,...,444131 (One string separated by ,)
- I have 3000 records in my Database with different numbers. (With numbers I mean some kind of ID)
- Of my 100 numbers only 8 are registered in my database.
Question:
How can I know what numbers are registered in the database and insert in other table the relationship?
My table Relationship have this columns:
*number1 - (Here should be my ID)
*number2 - (1 of the 100 numbers that exists)
So in my table Relationship should be 8 new rows.
I tried with :
EXEC('SELECT * FROM Accounts WHERE ID IN(' +#in_mystring+')')
but i don't know how insert in the other table or if is efficiently
Assuming this is SQL Server, and with the help of a parser function
For example
Select * from [dbo].[udf-Str-Parse]('7781,5913,551949194,4919491,...,444131',',')
Returns
Key_PS Key_Value
1 7781
2 5913
3 551949194
4 4919491
5 ...
6 444131
From this sub-query, you can join the results to your Accounts Table
Perhaps something like this
Select A.*
From Accounts A
Join (Select * from [dbo].[udf-Str-Parse]('7781,5913,551949194,4919491,...,444131',',')) B
on A.Key_Value =A.ID
The UDF -- If 2016, There is a native parser.
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
-- Select * from [dbo].[udf-Str-Parse]('id26,id46|id658,id967','|')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1) NOT NULL , Key_Value varchar(max))
As
Begin
Declare #intPos int,#SubStr varchar(max)
Set #IntPos = CharIndex(#delimeter, #String)
Set #String = Replace(#String,#delimeter+#delimeter,#delimeter)
While #IntPos > 0
Begin
Set #SubStr = Substring(#String, 0, #IntPos)
Insert into #ReturnTable (Key_Value) values (#SubStr)
Set #String = Replace(#String, #SubStr + #delimeter, '')
Set #IntPos = CharIndex(#delimeter, #String)
End
Insert into #ReturnTable (Key_Value) values (#String)
Return
End

How to compare date with a date range

I want to calculate Total of Quantity and GROUP BY CarID but am currently unable to do this.
In my database have some tables: TBL_CAR_TX, TBL_CAR, TBL_PERSON
table: TBL_CAR_TX
------------------
select * from TBL_CAR_TX
where TranDate >= '2011-06-09' and Trandate <= '2011-06-20'
TranID, AccID, CarID, TranDate, Type, Quantity, .....
--------------------------------------------------------
0 2563 BMW 2011-06-09 H -15 (1)
1 2563 BMW 2011-06-20 R 15
2 2563 BMW 2011-06-20 H 20
3 0055 TOY 2011-06-12 H -10 (2)
4 0055 TOY 2011-06-20 R 10
...
(H): Hold, (R): Release
if we change the condition of the WHERE stmt:
select * from TBL_CAR_TX where TranDate >= '2011-06-10' and Trandate <= '2011-06-19'
(these date, I get them from outside)
==> all of the records disappear ==> I can't calculate because the data doesn't display.
Look at the table TBL_CAR_TX, we can see that a person borrow car 'BMW' from '2011-06-09' and until '2011-06-20' he returned it. So If I do in SQL Server 2008, how can I keep the record (1) & (2) in the range date from '2011-06-10' to '2011-06-19' to calculate. If can not, how can I do it in java programming ? Any suggest.
table TBL_CAR:
MarketID, CarID, Name, Size, ...
---------------------------
GER BMW ....
JPA TOY ....
Table TBL_PERSON:
AccID, Name, Age, DOB, ...
-------------------------
2563 Robert
0055 Mike
Thanks you very much for your help
I want to calculate Total of Quantity and GROUP BY CarID but am currently unable to do this.
So If I do in SQL Server 2008, how can I keep the record (1) & (2) in
the range date from '2011-06-10' to '2011-06-19' to calculate.
Just get rid of = from your SQL.
select CarID, SUM(QUANTITY) from TBL_CAR_TX where TranDate > '2011-06-09' and Trandate < '2011-06-20' GROUP BY CarID
or use BETWEEN SQL CLAUSE.
select CarID, SUM(QUANTITY) from TBL_CAR_TX where TranDate BETWEEN '2011-06-10' AND '2011-06-19' GROUP BY CarID
If can not, how can I do it in java programming ?
You can definitely filter out the data in java but there is no point in doing so when SQL can do the work for you. Unless it is a massive performance penalty, it is almost always worth doing the processing like this in SQL.

Categories