I have two tables vtiger_crmentity and vtiger_crmentityrel (from open source project vtiger).
vtiger_crmentity
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| crmid | int(19) | NO | PRI | NULL | |
| smcreatorid | int(19) | NO | MUL | 0 | |
| smownerid | int(19) | NO | MUL | 0 | |
| modifiedby | int(19) | NO | MUL | 0 | |
| setype | varchar(30) | NO | | NULL | |
| description | text | YES | | NULL | |
| createdtime | datetime | NO | | NULL | |
| modifiedtime | datetime | NO | | NULL | |
| viewedtime | datetime | YES | | NULL | |
| status | varchar(50) | YES | | NULL | |
| version | int(19) | NO | | 0 | |
| presence | int(1) | YES | | 1 | |
| deleted | int(1) | NO | MUL | 0 | |
| label | varchar(255) | YES | MUL | NULL | |
+--------------+--------------+------+-----+---------+-------+
vtiger_crmentityrel
+-----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| crmid | int(11) | NO | | NULL | |
| module | varchar(100) | NO | | NULL | |
| relcrmid | int(11) | NO | | NULL | |
| relmodule | varchar(100) | NO | | NULL | |
+-----------+--------------+------+-----+---------+-------+
I am trying to get a list of contacts which are not present in the crmentityrel table (in the relcrmid column to be specific). I can do this via a subquery but it is taking about 2 minutes to complete (for about 20k records in each table).
I tried to convert the query to a join but i am surely doing something wrong as i keep getting wrong values (compared to the subquery which i know is right).
Any help is greatly appreciated. Please tell me if you need any details from my side
Edit -
My working query (with subquery) is -
SELECT crmid, label from vtiger_crmentity
WHERE deleted = 0 and setype="Contacts"
and crmid not in (select relcrmid from vtiger_crmentityrel
where relmodule="Contacts")
To convert a not in to a join, the idea is to use left join and where:
SELECT c.crmid, c.label
FROM vtiger_crmentity c left join
vtiger_crmentityrel cr
on c.crmid = cr.relcrmid and relmodule = 'Contacts'
WHERE c.deleted = 0 and c.setype = 'Contacts' and cr.relcrmid is null;
I should point out that the above is not exactly equivalent. NOT IN returns no rows if the subquery returns even a single NULL value. The above behaves more intuitively.
Because of the behavior of NOT IN with NULL values, NOT EXISTS is a better choice. Plus, it often has better performance as well:
SELECT crmid, label
FROM vtiger_crmentity c
WHERE deleted = 0 and setype = 'Contacts' AND
NOT EXISTS (SELECT relcrmid
FROM vtiger_crmentityrel cr
WHERE cr.relmodule = 'Contacts' and cr.relcrmid = c.crmid
);
I have trying to do a SELECT query....not an UPDATE or INSERT or DELETE.
I have three tables.
The customers table
The invoices table
The invoice_items table
I want to run a query that will show me every invoice. Each invoice can have only ONE customer and MANY items...hence the existence of invoice_items
My current query looks like this
SELECT i.order_date, c.name, thedata.info from invoices i inner join customers c ON (i.customer = c.id) right join ( select x.order, group_concat( concat(x.itemname,' ', x.itemdesc) separator "\n" ) as info from invoice_items x ) thedata on (i.id = thedata.order)
When I run this query, I receive one row that contains, one customer, one invoice, and a list of any an every item regardless of invoice id or customer...???
+---------------------+--------------+---------------------------------------------------------------------------------------------------------------------------------+
| order_date | name | info |
+---------------------+--------------+---------------------------------------------------------------------------------------------------------------------------------+
| 2014-01-23 20:39:20 | Joe Customer | Boxes for boxing
Shoes for shining
2" Hermosa Plank for bobblin
Boxes for boxing
bobbles for bobblin
Lot 297 Woodale Carmel Oak |
+---------------------+--------------+---------------------------------------------------------------------------------------------------------------------------------+
My goal is to receive this same list but show all customers along with THEIR items.
What am I doing wrong?
Here are the schemas, for those that need them.
Customers
+---------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | text | NO | | NULL | |
| ship_address | text | NO | | NULL | |
| ship_address2 | text | NO | | NULL | |
| ship_city | text | NO | | NULL | |
| ship_state | text | NO | | NULL | |
| ship_zip | int(6) | NO | | NULL | |
| bill_address | text | NO | | NULL | |
| bill_address2 | text | NO | | NULL | |
| bill_city | text | NO | | NULL | |
| bill_state | text | NO | | NULL | |
| bill_zip | text | NO | | NULL | |
| phone | bigint(20) | NO | | NULL | |
| email | text | NO | | NULL | |
+---------------+------------+------+-----+---------+----------------+
Invoices
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| customer | int(11) | NO | | NULL | |
| order_date | datetime | NO | | NULL | |
| status | text | NO | | NULL | |
| freightcost | double | NO | | NULL | |
+-------------+----------+------+-----+---------+----------------+
Invoice_items
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| order | int(11) | NO | | NULL | |
| qty | int(11) | NO | | NULL | |
| itemname | text | NO | | NULL | |
| itemdesc | text | NO | | NULL | |
| itemprice | double | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
try the below query, you need to use GROUP BY if you use GROUP_CONCAT().
SELECT i.order_date,
c.name,
group_concat( concat(x.itemname,' ', x.itemdesc) separator "\n" ) as info
FROM invoices i
INNER JOIN customers c ON i.customer = c.id
LEFT JOIN invoice_items x ON i.id = x.order
GROUP BY i.order_date,c.name
in my database I have 3 tables named items, manufacturers and items_manufacturers. manufacturers has a HAS:MANY relation with items_manufacturers
My items table
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| code | varchar(25) | NO | MUL | NULL | |
| item_category | varchar(100) | NO | | NULL | |
| item_desc | varchar(500) | NO | | NULL | |
| reorder_point | int(11) | NO | | NULL | |
| unit | varchar(45) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
My manufacturers table
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| code | varchar(25) | NO | | NULL | |
| name | varchar(250) | NO | | NULL | |
| address | varchar(750) | NO | | NULL | |
| contact_no | varchar(50) | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
My items_manufacturers table
+-----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| item_id | bigint(20) | NO | MUL | NULL | |
| manufacturer_id | bigint(20) | NO | MUL | NULL | |
| unit_cost | decimal(20,2) | NO | | NULL | |
| vendor_id | bigint(20) | NO | | NULL | |
+-----------------+---------------+------+-----+---------+----------------+
In my result table I want items_id, items_desc, name of manufacturer from manufacturers table and manufacturer_id. The relation I have is
items.id=items_manufacturers.item_id and
manufacturers.id=items_manufacturers.manufacturer_id.
I tried using inner joins for three tables but not working.
The query I tried
select
items_manufacturers.id,
items.item_desc,
item_manufacturers.manufacturer_id,
manufacturer.name
from items_manufacturers
INNER JOIN items ON items_manufacturers.item_id=items.id
INNER JOIN manufacturers ON items_manufacturers.manufacturer_id=manufacturers.id
Anybody kindly help me with this, I am stuck up from a long time
I used this following code and got the result you were trying to get. This code may solve your problem:
select a.name,b.manufacturer_id,c.id,c.item_desc
from manufacturers as a
inner join
item_manufacturers as b
on b.manufacturer_id=a.id
inner join item as c
on c.id=b.item_id
I am working with an Employee database in Mysql. My Db contains the following tables
mysql> describe edept;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| dept | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql>describe esal;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| basic | int(11) | NO | | NULL | |
| pf | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> describe edesig;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| desig | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
mysql> describe edetails;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| dept | int(11) | NO | MUL | NULL | |
| desig | int(11) | YES | MUL | NULL | |
| basic | int(11) | NO | MUL | NULL | |
| pf | int(11) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+-------+
I have to get values for dept,desig,basic,pf from the tables edept.dept,edesig.desig,esal.basic,esal.pf respectively.
I used foreign keys for all the fields for which i have to retrieve values from other tables.And i tried a sample inner join query. but i got the output as follows:
mysql> select * from edetails inner join edept on edetails.dept=edept.id;
+----+--------+-----+------+-------+-------+----+----+------------------+
| id | name | age | dept | desig | basic | pf | id | dept |
+----+--------+-----+------+-------+-------+----+----+------------------+
| 1 | swetha | 21 | 3 | 2 | 2 | 2 | 3 | Business Process |
+----+--------+-----+------+-------+-------+----+----+------------------+
My edept table contains the following:
mysql> select * from edept;
+----+------------------+
| id | dept |
+----+------------------+
| 3 | Business Process |
+----+------------------+
How can i eliminate duplicate columns. i need the value "business process" in the dept field of the edept table
Try this::
select
edetails.id,
edetails.name,
edetails.age,
edetails.dept,
edesig.desig,
edetails.basic,
edetails.pf,
edept.dept
from edetails
inner join edept on edetails.dept=edept.id
INNER JOIN edesig on edesig.id=edetails.desig
Hello i am trying to run this select statement using this query and it is taking over 2 hours to run. I have set up all the index's to be correct. But it still takes forever is there something i am missing or a more efficient way of joining tables together that will speed this query up?
I have indexes set up for all items being joined together and they are the same length and data type.
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
t.regular_discount
FROM part p
LEFT JOIN tabjbmaw t ON t.accountnum = '73050'
AND p.numeric_line_code = t.numeric_line_code
AND p.sub_code = t.sub_code
JOIN warehouse w ON w.sap_article_id = p.sap_article_id;
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
| 1 | SIMPLE | part | ALL | PRIMARY,sap_article,part_sap_article_id_fk | NULL | NULL | NULL | 389309 | |
| 1 | SIMPLE | warehouse | ref | article | article | 130 | inventory.part.sap_article_id | 5 | Using where |
| 1 | SIMPLE | tabjbmaw | ref | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx | 5 | inventory.part.numeric_line_code | 19 | |
+----+-------------+-----------+------+--------------------------------------------------+-----------------------+---------+----------------------------------+--------+-------------+
Thank you for your help
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
| sap_article_id | varchar(24) | NO | PRI | | |
| sap_brand_id | varchar(20) | NO | | NULL | |
| uag_partnum | varchar(20) | NO | MUL | NULL | |
| uag_linecode | varchar(5) | NO | MUL | NULL | |
| cag_partnum | varchar(20) | NO | MUL | NULL | |
| cag_linecode | varchar(5) | NO | | NULL | |
| product_category_legacy | varchar(20) | NO | | NULL | |
| part_description | varchar(128) | NO | | NULL | |
| abc_indicator | varchar(8) | NO | | NULL | |
| pack_code | varchar(8) | NO | | NULL | |
| case_qty | int(11) | NO | | NULL | |
| per_car_qty | int(11) | NO | | NULL | |
| uom | varchar(6) | NO | | NULL | |
| upc_code | varchar(128) | NO | | NULL | |
| jobber_price | float(14,4) | YES | | NULL | |
| jobber_core | float(14,4) | YES | | NULL | |
| date_last_price_change | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| weight | float(14,4) | YES | | NULL | |
| weight_unit | varchar(6) | NO | | NULL | |
| dimension_type | varchar(6) | NO | | NULL | |
| length | float(14,4) | YES | | NULL | |
| width | float(14,4) | YES | | NULL | |
| height | float(14,4) | YES | | NULL | |
| updated | tinyint(1) | NO | | 0 | |
| superseded_sap_article_id | varchar(24) | YES | | NULL | |
| last_updated | timestamp | NO | | 0000-00-00 00:00:00 | |
| hour_updated | int(11) | YES | | NULL | |
| discount1 | float | YES | | NULL | |
| discount2 | float | YES | | NULL | |
| product_category | varchar(3) | YES | | NULL | |
| superseded_part_number | varchar(20) | YES | | NULL | |
| sub_code | varchar(3) | YES | MUL | NULL | |
| date_effective_price_change | date | YES | | NULL | |
| numeric_line_code | varchar(3) | YES | MUL | NULL | |
| list | float | YES | | NULL | |
+-----------------------------+--------------+------+-----+---------------------+-----------------------------+
I have indexes set up for all items being joined together
Yes, but I am guessing from the names of the indexes that each index only has one field.
Let's look at a few columns in the describe.
| table | possible_keys | key
+-----------+--------------------------------------------------+----------------
| part | PRIMARY,sap_article,part_sap_article_id_fk | NULL
| warehouse | article | article
| tabjbmaw | numeric_line_code_idx,subcode_idx,accountnum_idx | numeric_line_code_idx
It can use an index for numeric_line_code, subcode, and accountnum, but there are only three indexes each with one of the fields, and no index which has all the fields. You are making the optimizer choose one of the one field indexes, instead of providing one index it can use for all three fields.
Add an index on table tabjbmaw with the three fields numeric_line_code, subcode, and accountnum.
Extending #Sebas answer, you should select tabjbmaw first:
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
t.regular_discount
FROM tabjbmaw t
LEFT JOIN parts p ON p.numeric_line_code = t.numeric_line_code
AND p.sub_code = t.sub_code
JOIN warehouse w ON w.sap_article_id = p.sap_article_id
WHERE t.accountnum = '73050'
;
You could try to put your Left Join into the SELECT part as a Subselect. That 'may' speed things up a little.
Like this:
SELECT
p.sap_article_id,
p.numeric_line_code,
p.uag_linecode,
p.uag_partnum,
p.part_description,
p.jobber_price,
p.jobber_core,
p.discount1,
p.discount2,
p.uom,
p.product_category,
w.as400_warehouse,
w.atp_qty,
p.updated,
(SELECT t.regular_discount FROM tabjbmaw t WHERE t.accountnum = '73050' AND p.numeric_line_code = t.numeric_line_code AND p.sub_code = t.sub_code LIMIT 1)
FROM
part p
JOIN warehouse w ON w.sap_article_id = p.sap_article_id;