I have two tables called transactions (TransactionID, HotelID, service..) and services (id, userid, HotelID, type) and I need to create view from there. In here 1st table has 15 tuples and 2nd one has 8 tuples.
When I wrote this SQL query:
CREATE VIEW summary
AS
SELECT TransactionID, userid, HotelID, service
FROM transactions, services
WHERE transactions.HotelID = services.name
I got 105 results in summary view. How I get rid of this duplication issue.
As far as i understands your question, i think you need to use group concate and group by using join query.
using group by and group concate duplication of record will be solve.
and using join you can get common data from both table.
try below query.
currently i am not having knowledge of your table structure that's why i take assumption of your query and created my own tables and as per them created query.
Eg:
select
c.country_id,c.country_name,group_concat(s.state_id),group_concat(s.state_name) from country c inner join state s on c.country_id =s.country_id group
by c.country_id;
if you have any query feel free to ask.
Related
So when the where clause isn't there the query works fine, but when I add it the query doesn't pull any results and just runs.
Basically what I'm trying to do is get all the customers who completed a survey on a website after 2021-11-17. One table has all the survey information whereas the other table has all the customer details which I need. customer_survey table has the survey details (reported_at date, survey_source (where they did the survey), customer_id) and the other table is Customers (email, phone number, last name, first name, id)
The where clause I'm trying to integrate is:
where survey_source = 'online' and reported_at > '2021-11-17'
This is the query that currently works:
SELECT customer_surveys.customer_id, customer_surveys.reported_at, customer_surveys.survey_source,customers.id,customers.last_name,customers.first_name,customers.home_phone, customers.work_phone,customers.email_address
FROM customer_surveys
JOIN customers on customer_surveys.customer_id = customers.id
If I understand correctly, this is the actual query which is hanging:
SELECT
c.id,
c.first_name,
c.last_name,
c.home_phone,
c.work_phone,
c.email_address,
c.reported_at,
c.survey_source
FROM customers c
INNER FROM customer_surveys cs
ON cs.customer_id = c.id
WHERE
cs.survey_source = 'online' AND
cs.reported_at > '2021-11-17';
One standard way to speed up the performance of this query would be to add one or more indices (indices = plural of index). For example, we can try adding the following index on the surveys table:
CREATE INDEX idx_survey ON customer_surveys (customer_id, survey_source, reported_at);
This index, if used, might help speed up the join condition.
When you run this query in SSMS, check what is the execution plan that is generated. Check if it suggests creating any indices. If there are huge no of records and the query is performing bad then you need to create indices on the fields that are involved in filtering the data viz customer_id, survey_source, reported_at.
I've got a problem with MySQL select statement.
I have a table with different Department and statuses, there are 4 statuses for every department, but for each month there are not always every single status but I would like to show it in the analytics graph that there is '0'.
I have a problem with select statement that it shows only existing statuses ( of course :D ).
Is it possible to create temporary table with all of the Departments , Statuses and amount of statuses as 0, then update it by values from other select?
Select statement and screen how it looks in perfect situation, and how it looks in bad situation :
SELECT utd.Departament,uts.statusDef as statusoforder,Count(uts.statusDef) as Ilosc_Statusow
FROM ur_tasks_details utd
INNER JOIN ur_tasks_status uts on utd.StatusOfOrder = uts.statusNR
WHERE month = 'Sierpien'
GROUP BY uts.statusDef,utd.Departament
Perfect scenario, now bad scenario :
I've tried with "union" statements but i don't know if there is a possibility to take only "the highest value" for every department.
example :
I've also heard about
With CTE tables, but I don't really get how to use it. Would love to get some tips on it!
Thanks for your help.
Use a cross join to generate the rows you want. Then use a left join and aggregation to bring in the data:
select d.Departament, uts.statusDef as statusoforder,
Count(uts.statusDef) as Ilosc_Statusow
from (select distinct utd.Departament
from ur_tasks_details utd
) d cross join
ur_tasks_status uts left join
ur_tasks_details utd
on utd.Departament = d.Departament and
utd.StatusOfOrder = uts.statusNR and
utd.month = 'Sierpien'
group by uts.statusDef, d.Departament;
The first subquery should be your source of all the departments.
I also suspect that month is in the details table, so that should be part of the on clause.
I'm trying to display ALL the fields for all entries in the table analysis which meet criteria in other tables, WITHOUT displaying any duplicate rows in analysis.
Because I want to show all the fields in analysis, I can't use DISTINCT. So I use wildcard with GROUP BY but the query returns fields not just in analysis. It's bringing in fields from personal and exam as well.
SELECT *
FROM analysis
JOIN personal
ON analysis.FirstName=personal.FirstName
AND analysis.LastName=personal.LastName
JOIN exam
ON personal.P_ID=exam.P_ID
WHERE exam.Level='B1'
AND exam.Certification='Full'
GROUP BY analysis.LastName
I can get what I want using DISTINCT and specifying EVERY field in analysis, but there are currently 13 fields, so I'd prefer some neater syntax than:
SELECT DISTINCT analysis.LastName, analysis.FirstName, analysis.X, analysis.y, ETC ETC
FROM analysis
JOIN personal
ON analysis.FirstName=personal.FirstName
AND analysis.LastName=personal.LastName
JOIN exam
ON personal.P_ID=exam.P_ID
WHERE exam.Level='B1'
AND exam.Certification='Full'
SELECT analysis.*
FROM analysis
JOIN personal
ON analysis.FirstName=personal.FirstName
AND analysis.LastName=personal.LastName
JOIN exam
ON personal.P_ID=exam.P_ID
WHERE exam.Level='B1'
AND exam.Certification='Full'
Try above code.
Hope this will helps.
I have what may be a basic performance question. I've done a lot of SQL queries, but not much in terms of complex inner joins and such. So, here it is:
I have a database with 4 tables, countries, territories, employees, and transactions.
The transactions links up with the employees and countries. The employees links up with the territories. In order to produce a required report, I'm running a PHP script that processes a SQL query against a mySQL database.
SELECT trans.transactionDate, agent.code, agent.type, trans.transactionAmount, agent.territory
FROM transactionTable as trans
INNER JOIN
(
SELECT agent1.code as code, agent1.type as type, territory.territory as territory FROM agentTable as agent1
INNER JOIN territoryTable as territory
ON agent1.zip=territory.zip
) AS agent
ON agent.code=trans.agent
ORDER BY trans.agent
There are about 50,000 records in the agent table, and over 200,000 in the transaction table. The other two are relatively tiny. It's taking about 7 minutes to run this query. And I haven't even inserted the fourth table yet, which needs to relate a field in the transactionTable (country) to a field in the countryTable (country) and return a field in the countryTable (region).
So, two questions:
Where would I logically put the connection between the transactionTable and the countryTable?
Can anyone suggest a way that this can be quickened up?
Thanks.
Your query should be equivalent to this:
SELECT tx.transactionDate,
a.code,
a.type,
tx.transactionAmount,
t.territory
FROM transactionTable tx,
agentTable a,
territoryTable t
WHERE tx.agent = a.code
AND a.zip = t.zip
ORDER BY tx.agent
or to this if you like to use JOIN:
SELECT tx.transactionDate,
a.code,
a.type,
tx.transactionAmount,
t.territory
FROM transactionTable tx
JOIN agentTable a ON tx.agent = a.code
JOIN territoryTable t ON a.zip = t.zip
ORDER BY tx.agent
In order to work fast, you must have following indexes on your tables:
CREATE INDEX transactionTable_agent ON transactionTable(agent);
CREATE INDEX territoryTable_zip ON territoryTable(zip);
CREATE INDEX agentTable_code ON agentTable(code);
(basically any field that is part of WHERE or JOIN constraint should be indexed).
That said, your table structure looks suspicious in a sense that it is joined by apparently non-unique fields like zip code. You really want to join by more unique entities, like agent id, transaction id and so on - otherwise expect your queries to generate a lot of redundant data and be really slow.
One more note: INNER JOIN is equivalent to simply JOIN, there is no reason to type redundant clause.
I am using the following JOIN statement:
SELECT *
FROM students2014
JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent)
WHERE students2014.Consultant='$Consultant'
ORDER BY students2014.LastName
to retrieve a list of students (students2014) and corresponding notes for each student stored in (notes2014).
Each student has multiple notes within the notes2014 table and each note has an ID that corresponds with each student's unique ID. The above statement is returning a the list of students but duplicating every student that has more than one note. I only want to display the latest note for each student (which is determined by the highest note ID).
Is this possible?
You need another join based on the MAX noteId you got from your select.
Something like this should do it (not tested; next time I'd recommed you to paste a link to http://sqlfiddle.com/ with your table structure and some sample data.
SELECT *
FROM students s
LEFT JOIN (
SELECT MAX(NoteId) max_id, NoteStudent
FROM notes
GROUP BY NoteStudent
) aux ON aux.NoteStudent = s.Student
LEFT JOIN notes n2 ON aux.max_id = n2.NoteId
If I may say so, the fact that a table is called students2014 is a big code smell. You'd be much better off with a students table and a year field, for many reasons (just a couple: you won't need to change your DB structure every year, querying across years is much, much easier, etc, etc). Perhaps you "inherited" this, but I thought I'd mention it.
GROUP the query by studentId and select the MAX of the noteId
Try :
SELECT
students2014.Student,
IFNULL(MAX(NoteId),0)
FROM students2014
LEFT JOIN notes2014 ON (students2014.Student = notes2014.NoteStudent)
WHERE students2014.Consultant='$Consultant'
GROUP BY students2014.Student
ORDER BY students2014.LastName