Can't deal with sql query.
There is a table of platforms.
I have a sales table.
There is a table of connection between platforms and games.
Table with games is the main.
Table chart
(https://i.stack.imgur.com/MxQDP.png)
Made sql query.
SELECT`Sales`.'Global_Sales', Platform.name
FROM `Games_In_Platform` INNER JOIN `Sales` ON `Games_In_Platform`.`game_id`=`Sales`.`game_id`
JOIN Platform on Games_In_Platform.platform_id = Platform.id;
Got two columns
Platforms and global sales
photo of the received table (https://i.stack.imgur.com/lEEhA.png)
How to group global sales by platform?
Output the arithmetic mean of global sales for each platform?
And do it in one request!
Use the AVG (average) aggregate function and put column that isn't aggregated (the name) into the group by clause.
SELECT avg(`Sales`.'Global_Sales') as average_sales, --> this
Platform.name
FROM `Games_In_Platform` INNER JOIN `Sales` ON `Games_In_Platform`.`game_id`=`Sales`.`game_id`
JOIN Platform on Games_In_Platform.platform_id = Platform.id
group by Platform.name --> and this
As you commented that average isn't calculated correctly: it is not about the function, it works OK. For example:
SQL> select name, sales from test order by name;
NAME SALES
------ ----------
name A 100 --> average for "name A" = (100 + 200) / 2
name A 200 --> = 300 / 2 = 150
name B 50 --> average for "name B" = 50 / 1 = 50
So, what does the function return? It returns what we expect:
SQL> select name,
2 avg(sales) average_sales
3 from test
4 group by name;
NAME AVERAGE_SALES
------ -------------
name A 150
name B 50
SQL>
Therefore, if query returns unexpected result, do provide some sample data so that we'd see what's going on.
Related
I have a use case, where I have to merge data from 2 Tables (which are in different data sources).
Consider that each table has employee data (First name, last name, phoneNumber). For each employee, I will have to merge the phoneNumber data from both the Tables and other data will remain the same as in Table 1
If employee data is present in both Table 1 and Table 2, phoneNumber data will be merged as a comma separated values and other data will be sourced from Table 1
If employee is present only in Table 1, then entire data will be sourced from Table 1
If employee is present only in Table 2, then entire data will be sourced from Table 2
These Tables has about 40 lack rows of data each. Close to 5GB.
What is the best approach to do this in Java? My concern is if I pull the data from these 2 tables into Java cache, i will still have to loop thought the entire table 2 to see if an employee is present there as well.
Or will a python script be better?
Table 1
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
12345
EM02
Dave
Joe
34567
Table 2:
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
89000
EM03
Gabe
Mai
45678
Table 3 (After merging the phone numbers):
EmployeeID
FirstName
LastName
PhoneNumber
EM01
Jhon
Doe
12345,89000
EM02
Dave
Joe
34567
EM03
Gabe
Mai
45678
You can easily do this as a SQL query.
Basically, you want a full join, but -- alas -- MySQL doesn't support that.
So, one method is:
select t1.EmployeeID, t1.FirstName, t1.LastName
concat_ws(',', t1.PhoneNumber, t2.PhoneNumber) as PhoneNumber
from table1 t1 left join
table2 t2
on t1.EmployeeID = t2.EmployeeID
union all
select t2.EmployeeID, t2.FirstName, t2.LastName, t2.PhoneNumber
from table2 t2
table1 t1 left join
on t1.EmployeeID = t1.EmployeeID
where t1.EmployeeID is null;
That is, get all the rows for the employees in table1. Then add in the additional rows from table2. For the first part, concat_ws() is convenient for combining the phone numbers.
I need union equivelant for Union. I know we can do this by joining selections but i couldn't do that for adding constant to query results. Here is my sql
SELECT MIN(t1.EXAMPLE_NUMBER)
FROM
(
SELECT 1 AS EXAMPLE_NUMBER
UNION ALL
SELECT EXAMPLE_NUMBER + 1
FROM selection.SELECTION
) t1
LEFT OUTER JOIN selection.SELECTION t2
ON t1.EXAMPLE_NUMBER = t2.EXAMPLE_NUMBER
WHERE t2.EXAMPLE_NUMBER IS NULL;
This query need for finding minimum unused integer for the column. Lets say:
EXAMPLE_NUMBER
1
4
5
I need to get 2 as a result for this case. That is the sql for this. So here is my question:
I use QueryDsl-JPA for this. Since JPA 2, i can't use UNION. So i can't do this sql with querydsl-jpa, i was thinking about go like this:
JPAQuery baseQuery = new JPAQuery(em);
SubQueryExpression handleNumberOne = baseQuery.select(Expressions.constant(1));
SubQueryExpression selectAvailableMinNumber = baseQuery.select(selection.exampleNumber.add(1)).from(selection);
baseQuery.union(handleNumberOne, selectAvailableMinNumber); // NO UNION AVAILABLE
Is it any available way to do this with querydsl-JPA? I don't want to include querydsl-sql library just for this reason, I'm looking for JPA style solution. What i tried so for to try adding constant (1 in my case) to result of select query without union. By this way I may able to continue. Any suggestion?
You do not have to generate all the numbers to get this information.
For all numbers except 1, you can do:
select s.example_number + 1
from selection s
where not exists (select 1
from selection s2
where s2.example_number = s.example_number + 1
)
fetch first 1 row only; -- or limit 1
If you also want to get "1" if it doesn't exist, then:
select (case when min_en > 1 then 1
else s.example_number + 1
end)
from selection s cross join
(select min(example_number) as min_en from selection) mins
where not exists (select 1
from selection s2
where s2.example_number = s.example_number + 1
)
fetch first 1 row only; -- or limit 1
I have a scenario where i need to take count of rows in mysql table for the current branch(in that table we are store branch) and insert the count of rows with other details into the same table. But the problem is when two or more concurrent users try to insert from the same branch at the same time the count is same for all the users, but for me the insert should not happ for the other user(s) until i read the count and insert that one user request . Is there any way the locking works for this and any example would be helpful(All i need to do this in MySql store procedure)
Edit : Sorry, I cant share the working code but i can write example here
My table structure is here
id name branchid count
1 abc 1 1
2 xyz 1 2
3 abcd 2 1
4 wxyz 2 2
Here am taking count of rows from the above table for given branch(ex : 1) and inserting the row with that calculated count
Ex :
set #count = (select count(id) from tbl where branchid = 1);
later
insert into tbl(id, name, branchid, count)
values(5, 'abcd', 1, #count)
This works great provided if only one user access this from one branch , but if more than one user from same branch try to access this at exact same time the
#count
is duplicating for the branch users.
Why not just do it in one query:
insert into tbl(id, name, branchid, count)
select 5, 'abcd', 1, count(*)
from from tbl
where branchid = 1;
I am trying to get data for all dates in a range provided by my query, but I'm only getting the dates that actually exist in my table - missing dates are not reported. I need to create records in the table for those missing dates, with other columns left null, and then include them in the results.
My table table_name has records like:
ID Name Date_only
---- ---- -----------
1234 xyz 01-Jan-2014
1234 xyz 02-Jan-2014
1234 xyz 04-Jan-2014
...
For example, for the range 01-Jan-2014 to 04-Jan-2014, my query is:
select * from table_name
where id=1234
and (date_only >= '01-Jan-14' and date_only <= '04-Jan-14')
From Java or queried directly this shows three rows, with no data for 03-Jan-2014.
I need a single statement to insert rows for any missing dates into the table and return the data for all four rows. How can I do that?
UPDATE
Followed query worked for only if only 1 record available in table OR search range 2-5 days,
SELECT LEVEL, to_date('2014-11-08','yyyy-mm-dd') + level as day_as_date FROM DUAL CONNECT BY LEVEL <= 10 .
UPDATE WITH FIDDLE EXAMPLE
I got Error is:
I have table data and same query executed then i got error is ORA-02393: exceeded call limit on CPU usage, fiddle example is : my owntable sqlfiddle example .thanks in advance
you can use the below SQL for your purpose.The sql fiddle here http://sqlfiddle.com/#!4/3ee61/27
with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where id='1001'
and onlydate >= to_date('01-Jan-2015','dd-Mon-YYYY')
and onlydate <= to_date('04-Jan-2015','dd-Mon-YYYY')),
missing_dates as (select min_date + level-1 as date_value
from start_and_end_dates connect by level <=(max_date - min_date) + 1)
select distinct id,name,date_value
from mytable,missing_dates
where id='1001'
order by date_value
EDIT1:- Using your other example.The sqlfiddle is http://sqlfiddle.com/#!4/4c727/16
with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where name='ABCD'),
missing_dates as (select min_date + level-1 as date_value
from start_and_end_dates connect by level <=(max_date - min_date) + 1)
select distinct id,name,date_value
from mytable,missing_dates
where name='ABCD'
order by date_value;
You can use a query like
SELECT LEVEL, to_date('2014-01-01','yyyy-mm-dd') + level as day_as_date
FROM DUAL
CONNECT BY LEVEL <= 1000
to get a list of 1000 days from Jan 1 2014 (adjust to your need)
Next do an insert from select
INSERT INTO table_name (date_only)
SELECT day_as_date FROM (<<THE_QUERY_ABOVE>>)
WHERE day_as_date NOT IN (SELECT date_only FROM table_name)
in our chat application, the following is the case, there is person 'A' who have chat with person 'B' in two cases,1) one-to-one chat and 2) group chat. so in the database records are as follows,
Table : core
id name
1 A
2 B
3 C
Table : Master
id core_id
1 1
2 2
Table : recepient
id core_id master_id
1 1 1
2 2 1
3 1 2
4 2 2
5 3 2
so in the recepient table, we have 2 entries for Person 'A'. Now the problem is, i want the master_id = 1 form recepient table, in which person 'A' and 'B' are communicated. But there are two entries in recepient table for this. so how to get that id?
It's unclear what you are asking and your table names do not assist in making this any clearer. However, I suspect you are selecting records from the recipient table based only on the master_id and need to join with the other tables so that you can also include the name in the query.
So with this in mind, try the following (caveat: I haven't tested this, and I work with Oracle not mysql) but:
select *
from core c, master m, recipient r
where c.id = m.core_id
and c.id = r.core_id
and m.id = r.master_id
and c.name = 'A'
And before anyone complains that this sql does not follow the latest ANSI standard, it's the way I do it and it works for me!