comparing two table columns in mysql results in duplicate - mysql

I have two tables, I've been trying to print the result from each but they are being duplicated. These are the two MySQL tables and the result. Notice the duplication.
The sql code for the project is:
SELECT * FROM savings,savtype WHERE cust_id=".$_SESSION['user']
I'm also looking for a work around this, in the meantime, id appreciate any assistance on this.

because you are not specifying how the two tables are related. You need to add that, either via an explicit ... JOIN ... (USING|ON)
SELECT
*
FROM
savings JOIN savtype USING (savtype_id)
WHERE
cust_id = ".$_SESSION['user']
or by providing the criteria in the where clause.
SELECT
*
FROM
savings, savtype
WHERE
savings.savtype_id = savtype.savtype_id AND
cust_id = ".$_SESSION['user']

As I understand from the screenshot you added, it makes joint between those tables, and what you probably want it left join from savings and savtype tables.
SELECT *
FROM `savings`
LEFT JOIN `savtype`
ON savings.savtype_id=savtype.savtype_id
where cust_id=".$_SESSION['user'] .";
Update if this did the trick,
You can learn more about left join here: https://www.w3schools.com/sql/sql_join_left.asp

Related

MySQL join two completely identical tables with WHERE

I have two of same tables with different names. The first one's name is "folders" and the second one is "folders_archive".
I like to INNER JOIN this two tables with thier full content by filtering it on a date. If I use two single query's, thats works fine, but the joined query has no result.
I like something like this:
SELECT *
FROM folders
INNER JOIN folders_archiv
ON folders_archiv.id= folders.id
WHERE folders_archiv.datum = '".$year."-".$month."-".$day."'
AND folders.datum = '".$year."-".$month."-".$day."';
I'm trying to connect these tables in several way, but something is wrong with my logic, please help to fix it.
Thanks.
You question is not very clear, by i think you need Union - gives you all records from two table without repeat(if repeat is acceptable use union all). For example:
select t1.* from (
SELECT column_names
FROM folders
UNION
SELECT column_names
FROM folders_archive) t1
WHERE t1.column_names = what_you_want;
Very vague question.
But try this:
SELECT *
FROM folders
INNER JOIN folders_archiv
ON folders_archiv.datum= folders.datum
WHERE folders_archiv.datum = '".$year."-".$month."-".$day."'

Query to join 3 tables

I need to write a query to join 3 tables.
My tables are:
ucommerce_customer
ucommerce_order
ucommerce_order_line
All 3 tables have a column called order_id.
The table ucommerce_order has a column called order_status.
When the order_status is set to "open" I want to display the order details.
ResultSet myRs = myStmt.executeQuery
("SELECT * FROM ucommerce_customer
INNER JOIN ucommerce_order
INNER JOIN ucommerce_order_line
WHERE ucommerce_order.order_status = 'open'");
My query ignores the order status and displays all orders, open and closed.
Also I have several products so ucommerce_order_line has several entries for the same order_id, my query displays duplicate entries and it duplicates the entire list as well.
How can I write a query that will show only open orders without duplicating everything?
In MySQL, the on/using clause is optional. This is very sad because someone can make mistakes like you did. Your question only mentions one column, so perhaps that is all that is needed for the join:
SELECT *
FROM ucommerce_customer INNER JOIN
ucommerce_order
USING (orderId) INNER JOIN
ucommerce_order_line
USING (OrderId)
WHERE ucommerce_order.order_status = 'open';
I would be surprised if the customer table really had a column called OrderId (seems like a bad idea in most situations), so the first USING clause might want to use CustomerId.
I would recommend to use a natural join instead. Maybe that's where the errors are coming from.
The duplicates can be removed by running SELECT DISTINCT * ...

Populate 'temporary' columns with corresponding values during MySQL join query, also limit

I'm doing several MySQL joins to get template variables (i.e. custom fields) and their values (in MODX Evo but it's irrelevant - this is a general MySQL query).
I'm looking ideally to be able to create 2 temporary columns in order to use SORT BY in the query, or something to this effect. I'd like to populate the values for 'event_date' and 'event_featured' for their corresponding id's in these new columns - then I could then sort the results by these columns.
On a very related note I would like to limit the results to 20 for each unique id, not for each row as would happen if I added LIMIT- it would crop the below result to the . Can this be accomplished at the same time?
Anybody know how / if these are possible? Many thanks in advance.
Code and image of the results below:
SELECT DISTINCT
content.id, content.pagetitle, content.template , content.published,
templates.templatename,
tv_props.name,
tv_values.value
FROM `modx_site_content` AS `content`
LEFT JOIN `modx_site_templates` AS `templates` ON content.template=templates.id
LEFT JOIN `modx_site_tmplvar_templates` AS `template_tvs` ON templates.id=template_tvs.templateid
LEFT JOIN `modx_site_tmplvars` AS `tv_props` ON template_tvs.tmplvarid=tv_props.id
LEFT JOIN `modx_site_tmplvar_contentvalues` AS `tv_values` ON template_tvs.tmplvarid=tv_values.tmplvarid
WHERE templates.id=89
AND (
tv_props.name='event_featured'
OR tv_props.name='event_link_through'
OR tv_props.name='event_title'
OR tv_props.name='event_date'
OR tv_props.name='event_date_text'
OR tv_props.name='event_short_description'
OR tv_props.name='event_list_image'
);
Link to full-size image
You're going to need a couple of virtual tables, also known as subqueries, to retrieve these two properties of events from your name/value table. The generic name for this kind of query is a "pivot," for your information.
The mental knack is to think of the subquery as a virtual table which you can use in a surrounding query. The subquery for event_date looks like this, I believe.
SELECT content.id AS id,
tv_values.value AS event_date
FROM modx_site_content AS content
LEFT JOIN modx_site_templates AS templates
ON content.template=templates.id
LEFT JOIN modx_site_tmplvar_templates AS template_tvs
ON templates.id=template_tvs.templateid
LEFT JOIN modx_site_tmplvars AS tv_props
ON template_tvs.tmplvarid=tv_props.id
LEFT JOIN modx_site_tmplvar_contentvalues AS tv_values
ON template_tvs.tmplvarid=tv_values.tmplvarid
WHERE tv_props.name = 'event_date'
This little query produces a resultset that's a table relating content id to event date. I honestly don't understand your schema well enough to know if there's just one event date for each content id, so you might need to adjust this query to SELECT more columns. As you debug this, you should try out the subquery and make sure it's giving the results you hope for.
Then, when you're sure the subquery is OK, you join that subquery into your overall query, generically like so.
SELECT DISTINCT
content.id, event_date.event_date, templates.column,
table.column, table.colum, etc, etc
FROM modx_site_content AS content
LEFT JOIN table ON condition
LEFT JOIN (
SELECT content.id AS id,
tv_values.value AS event_date
FROM modx_site_content AS content
LEFT JOIN modx_site_templates AS templates
ON content.template=templates.id
LEFT JOIN modx_site_tmplvar_templates AS template_tvs
ON templates.id=template_tvs.templateid
LEFT JOIN modx_site_tmplvars AS tv_props
ON template_tvs.tmplvarid=tv_props.id
LEFT JOIN modx_site_tmplvar_contentvalues AS tv_values
ON template_tvs.tmplvarid=tv_values.tmplvarid
WHERE tv_props.name = 'event_date'
) AS event_date ON event_date.id = content.id
LEFT JOIN etc, etc, etc.
WHERE etc etc etc
Do you see how that goes? You can use tablename AS table or (some query) AS table interchangeably. You can also define a VIEW in your schema that provides the same data, and name it in your query. That's a handy way to make your queries less hairy.
By the way, you'll boost performance if you change
AND (
tv_props.name='event_featured'
OR tv_props.name='event_link_through'
OR tv_props.name='event_title' etc )
to
AND tv.props.name IN ('event_featured',
'event_link_through',
'event_title', etc)
You've probably noticed I'm a bit of a stickler for indentation in SQL queries. I find this helpful; I often find mistakes while I'm fixing up the indentation. Your practice may vary.

MySQL Query Join 2 tables with 2 relationship tables

I have a real mindbender of a MySQL problem which I am now thinking there is no answer to. Please help me, you are my only hope!
Stripping it down to the basics, I have two tables, "People" and "Activity". It is possible (long story and lots of data involved) for these two tables to be joined by two different relationship tables: people_activity and entity_activity
I need to do a query on the activity table which gets the people record/s linked to activity records based on both relationship tables.
This is what I have, but it is massively slow on lots of data:
select * from activity
left join peopleactivity on peopleactivity.activityid = activity.activityid
left join entityactivity on entityactivity.activityid = activity.activityid
left join people on (peopleactivity.peopleid = people.peopleid OR
entityactivity.entityid = people.peopleid)
Some more notes - I have also tried creating a view to combine the results of the two relationship tables and instead joining people and activity via this view. This also works, but is also still massively slow
Changing how the relationship/s work to consolodate to one table is a major headache
I have also tried a union -like this -
select * from activity
left join peopleactivity on peopleactivity.activityid = activity.activityid
left join people on (peopleactivity.peopleid = people.peopleid)
union
select * from activity
left join peopleactivity on peopleactivity.activityid = activity.activityid
left join people on (entityactivity.entityid= people.peopleid)
which also works, but for other reasons causes me problems. I really need to do this in one query without changing too much underlying.
Has anyone got any super amazing ideas that I have missed??!
You may try to replace OR with IN
left join people on people.peopleid IN (peopleactivity.peopleid, entityactivity.entityid)
1.) Try setting the id of the tables as the primary key on each table
2.) Use inner joins instead of left joins. Not sure why you are using left joins here as you will get all the results of the other tables left joined on the activity table and get basically all records whether or not they have a join value in another table. I think this might also help you. Can you post a describe of your tables.
I think you should keep the UNION query but making those INNER joins. Do you really need LEFT joins?
You could also change it into UNION ALL, which will have some performance gain:
SELECT activity.*, people.*, 'PA' AS joining_table
FROM activity
JOIN peopleactivity ON peopleactivity.activityid = activity.activityid
JOIN people ON peopleactivity.peopleid = people.peopleid
UNION ALL
SELECT activity.*, people.*, 'EA'
FROM activity
JOIN entityactivity ON entityactivity.activityid = activity.activityid
JOIN people ON entityactivity.entityid = people.peopleid
Thanks for the comments. I had tried various incarnations of the above. My answer was to set up a new table, copy all the existing links into that table, and then use triggers to add/remove links to that table whenever the links were added removed in the two separate link tables. This works well and also allows me to use indexes on this new table to keep things nice and snappy. Many thanks for those that took the time to post the ideas though!

How to select from database with relations?

I have database with schema on picture below and I need to select everything related to one row (one id) of [letaky]. That means the related [zamestnanci], every related [obsah] and every [knihy] in it.
This is the first time i used relations in database and i have no idea how to make such a select.
Use JOIN ... ON:
SELECT *
FROM zamestnanci
JOIN lekaty ON lekaty.zamestnanciid = zamestnanci.id
JOIN obsah ON obsah.idletaku = lekaty.id
JOIN knihy ON knihy.id = obsah.idknihy
WHERE letaky.id = 123
You may also want to consider whether you need INNER JOIN, LEFT JOIN or RIGHT JOIN for each of these joins. The difference between these JOINs is described in many other questions on StackOverflow, for example this one:
SQL Join Differences