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.
Related
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
i have a following PREFERENCE_SCORE table
ID(int) | SCORE(Double) | RANKING(int) |
I want to insert into database using the following code
String sql = "INSERT INTO PREFERENCE_SCORE_ ( ID,
SCORE,RANK) VALUES (?,?,?) ";
String query ="SELECT ID,FPIS,FNIS FROM db_housekeep";
ResultSet rsp = stats.executeQuery(query);
while(rsp.next()){
int id = rsp.getInt(1);
double fpis = rsp.getDouble(2);
double fnis = rsp.getDouble(3);
prSt.setInt(1, id);
prSt.setDouble(2, fnis/(fnis+fpis));
prSt.setInt(3, THIS PART i dont understand)
prSt.executeUpdate();
}
What should i add so the RANKING column is automatically filled by the rank of the data according to the SCORE column?
I think this approach is not beneficial. It will generate ambiguous data for rank.
e.g. if we insert the first row with (score 99) the rank will be 1 and after it, we insert the second row with score 100 what is the rank? (according to runtime calculation rant should 1 but we have already 1 so what can we do?).
So, its prefer to use it only will select data from the table for showing.
Hopefully, you know the syntax as ( RANK ( ) OVER ( [ partition_by_clause ] order_by_clause ) )
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
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
Below is the original content of a hibernate sql query I have:
<sql-query name="countryOfOrigin-limit-country-city-location">
<return alias="rb" class="RecentBooking"/>
SELECT
bb.reserv_num as {rb.reservNum},
bb.origin as {rb.countryOfOrigin},
bb.pick_up_loc as {rb.locationId},
bb.first_date as {rb.bookingDate},
bb.pick_up_time as {rb.pickUpDate},
bb.drop_off_time as {rb.dropOffDate},
bb.car_price as {rb.carPrice},
bb.discount as {rb.discount},
bb.exchange_rate as {rb.exchangeRate},
SUBSTRING(a.internal_class,1,1)as {rb.carClass},
a.car_type as {rb.carType},
bb.vehicle_type as {rb.vehicleType},
s.name as {rb.supplier},
vv.country as {rb.country},
vv.city as {rb.city},
vv.location as {rb.location},
bb.cur as {rb.currency},
a.pics as {rb.carImage}
FROM (SELECT * FROM b WHERE first_date > DATE(NOW()-1)AS bb
JOIN a a ON a.id = bb.car_id
JOIN d d ON d.id = bb.pick_up_loc
JOIN supplier s ON s.id = d.supplier_id
JOIN v_location_trans vv ON vv.location_id = d.location_id
AND vv.lang=33
AND vv.country = :country
AND vv.city = :city
AND vv.location = :location
AND bb.origin = :countryOfOrigin
ORDER BY bb.id DESC
LIMIT :limit
</sql-query>
The sql runs fast enough, but as you might have noticed there is a big, the NOW()-1 should be NOW() - INTERVAL 1 DAY.
I modified the nested select statement as follows:
FROM (SELECT * FROM b WHERE first_date > DATE(NOW() - INTERVAL 1 DAY)) AS bb
The fix works fine in terms of results, however the query slows down massively (pretty much almost instant up to a few seconds).
I believe this is because the DATE(NOW() - INTERVAL 1 DAY) is being evaluated a large number of times (we have a very large data set). How would I go about seperating this calculation so that it only occurs once, without having to pass it in from java code like the country, city, limit, etc?
I have very little experience with hibernate or SQL, and I have tried seperating the calculation out into a variable before the select statement, which isnt allowed. I have also tried making small changes to the SQL query but I keep getting runtime errors, presumably due to invalid SQL.
How would I go about doing this?
Thanks.
You are creating a new temp table bb in your query on the whole record.
I would suggest that you should filter out the result in creating the temp table.
for example if you put the AND clause while creating temp table
AND bb.origin = :countryOfOrigin
Like:
FROM (SELECT * FROM b WHERE first_date > (NOW() - INTERVAL 1 DAY) AND origin = :countryOfOrigin)AS bb
Also you can put the limit it it as well.
FROM (SELECT * FROM b WHERE first_date > (NOW() - INTERVAL 1 DAY) AND origin = :countryOfOrigin LIMIT :limit)AS bb
EDITED -- New Answer.
I thing you do not need to change the INTERVAL 1 DAY, you stick to the previous query but replace the 1 with 86400000 which is equal to INTERVAL 1 DAY (24*60*60*1000)
new query would look like
FROM (SELECT * FROM b WHERE first_date > (NOW() - 86400000)
AND origin = :countryOfOrigin LIMIT :limit) AS bb