Exclude records from Query Builder Laravel - php

My table have these data:
ID | company_id | code | description
01 | NULL | CD01 | Standard description CD01
02 | NULL | XYZU | Standard description XYZU
03 | 1 | CD01 | Custom description CD01 for company 1
04 | 2 | CD01 | Custom description CD01 for company 2
I need to extract all 'code' from this table but showing a single product code only once.
If exists a record witht company_id <> '' I show that, instead if doesn't exists I show the record with standard description.
Starting from the sample data, if I wanted to show the articles for the company_id = 1, I expect to have this output:
ID | company_id | code | description
02 | NULL | XYZU | Standard description XYZU
03 | 1 | CD01 | Custom description CD01 for company 1
Have you got some suggest to do it?
Thank you

for removing duplicate entries from database results by group by you should disable ONLY_FULL_GROUP_BY for mysql. don't do that in mysql and don't disable strict mode! laravel itself sets some modes.
this is the overall solution for disabling this mode.
but in laravel you should also try another thing:
go to YouProjectFolder/vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php
at the end of the file fin strict_mode() function and just remove ONLY_FULL_GROUP_BY fr0m the string within the function.
(i just saw this solution in a stackoverflow post. unfortunately i didn't find that post)

Related

WordPress Duplicate term_id resulting in MultiSite Errors

We have some users that have added the same tag and category to a blog. When they do this, they are unable to edit or use those tags / categories and receive an error basically stating “You need a higher level of permission.”
So far i've determined the actual error being thrown is Term ID is shared between multiple taxonomies error that we have been receiving when trying to edit / delete certain post categories or post tags.
Debugging this further, the issue seems to be happening at creation time. When I look at the tables in the database the terms table looks fine, but the term_taxonomy table does not. The same term_id is being saved for both entries.
MariaDB [wordpress]> select * from wp_62_terms;
+---------+-----------------------+-----------------------+------------+
| term_id | name | slug | term_group |
+---------+-----------------------+-----------------------+------------+
| 1 | Uncategorized | uncategorized | 0 |
| 2 | Blogroll | blogroll | 0 |
| 107691 | ppppp | ppppp | 0 |
| 107692 | ppppp | ppppp | 0 |
+---------+-----------------------+-----------------------+------------+
MariaDB [wordpress]> select * from wp_62_term_taxonomy;
+------------------+---------+---------------+-------------+--------+-------+
| term_taxonomy_id | term_id | taxonomy | description | parent | count |
+------------------+---------+---------------+-------------+--------+-------+
| 1 | 1 | category | | 0 | 19 |
| 2 | 2 | link_category | | 0 | 0 |
| 34 | 107691 | post_tag | | 0 | 0 |
| 35 | 107691 | category | | 0 | 0 |
+------------------+---------+---------------+-------------+--------+-------+
I have been debugging this further and captured the $wpdb->last_query value for that able insert and those read as follows:
INSERT INTO `wp_62_term_taxonomy` (`term_id`, `taxonomy`, `description`, `parent`, `count`) VALUES (107691, 'post_tag', '', 0, 0)
INSERT INTO `wp_62_term_taxonomy` (`term_id`, `taxonomy`, `description`, `parent`, `count`) VALUES (107692, 'category', '', 0, 0)
The INSERT sql shows the correct term_id however - that is not what is getting stored in the database.
Manually updating the database value does correct the problem.
Any thoughts / ideas are appreciated!
This issue was caused by what seems to be a legacy and a potentially unused feature of WordPress Multisite. When the global_terms_enabled value is enabled in the wp_sitemeta table, it will create a global term list in the wp_sitecategories table.
Within the wp-includes\ms-functions.php file, the global_terms function is called when a new taxonomy term is added. Within that function, it does a check in the wp_sitecategories table to see if that term exists. However - that logic in that function is flawed and does not account for the same value across multiple taxonomies. It detects it as a duplicate, and then issues wpdb queries to change the term_id values as noted above.
This was logged as a bug in the WordPress Core here: https://core.trac.wordpress.org/ticket/55979
Changing the sitemeta value of global_terms_enabled from 1 to 0 solved this behavior.

How to identify which table to delete a record when data coming from two tables?

I have two tables where some same kind of information kept. One table has approved information and other one contains pending(waiting for approval) data. I fetch data from both table and display in a same view. So user will see data from both the tables. User can delete those records. But when deleting I've a trouble with finding out which table I should delete.
Assume, table1(Approved info), table2(Pending info)
table1
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 100 |
11 | test2 | N/A | 100 |
12 | test3 | N/A | 101 |
13 | test4 | N/A | 200 |
table2
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 105 |
11 | test2 | N/A | 103 |
12 | test3 | N/A | 106 |
13 | test4 | N/A | 202 |
table1 has a record with id of 10; and table2 has a record with id of 10 in that table. Id is the primary key of both tables. Both record will show to user. Let's say user wants to delete the record related to id 12 came from table2. So I want to delete that record from table2. But how can I figure out which table to delete that record. Because I can't use id to figure out the table. I have tried using some kind of data attribute attached with
data coming from table2 to differentiate them. But anyone can change them by inspecting it. So what is the proper way for solve this issue?
On any case, on any system, makes sense to have two to tables with same columns. That should be one of the firsts rules of database design. What's more, you discovered yourself how hard is to maintain a design like that. I see this on legacy systems developed with zero love to the code. In the future this will turn into a snowball. You should change it as soon as possible.
status column
The status of and entity or resource, is classic requirement, usually implemented with one little column which called : status, flag, mode, etc. In your case, it could have these values (#BhaumikPandhi comment):
pending/approved/rejected
id | name | description | creator | status |
--------------------------------------------
10 | test1 | N/A | 100 | pending|
If you are worried to the database optimization, you could use a tinyint with these equivalence in your documentation:
1 = pending
2 = approved
3 = rejected
status table
You could keep your first table called record
id | name | description | creator |
And create another one called record_status with 2 columns, in which record_id is a FK of record table
record_id | status |
Anyway, the status column is the most easy a classic approach to your requirement.

How should I Query this in mysql

I have a web app in which I show a series of posts based on this table schema (there are thousands of rows like this and other columns too (removed as not required for this question)) :-
+---------+----------+----------+
| ID | COL1 | COL2 |
+---------+----------+----------+
| 1 | NULL | ---- |
| 2 | --- | NULL |
| 3 | NULL | ---- |
| 4 | --- | NULL |
| 5 | NULL | NULL |
| 6 | --- | NULL |
| 7 | NULL | ---- |
| 8 | --- | NULL |
+---------+----------+----------+
And I use this query :-
SELECT * from `TABLE` WHERE `COL1` IS NOT NULL AND `COL2` IS NULL ORDER BY `COL1`;
And the resultant result set I get is like:-
+---------+----------+----------+
| ID | COL1 | COL2 |
+---------+----------+----------+
| 12 | --- | NULL |
| 1 | --- | NULL |
| 6 | --- | NULL |
| 8 | --- | NULL |
| 11 | --- | NULL |
| 13 | --- | NULL |
| 5 | --- | NULL |
| 9 | --- | NULL |
| 17 | --- | NULL |
| 21 | --- | NULL |
| 23 | --- | NULL |
| 4 | --- | NULL |
| 32 | --- | NULL |
| 58 | --- | NULL |
| 61 | --- | NULL |
| 43 | --- | NULL |
+---------+----------+----------+
Notice that the IDs column is jumbled thanks to the order by clause.
I have proper indexes to optimize these queries.
Now, let me explain the real problem. I have a lazy-load kind of functionality in my web-app. So, I display around 10 posts per page by using a LIMIT 10 after the query for the first page.
We are good till here. But, the real problem comes when I have to load the second page. What do I query now? I do not want the posts to be repeated. And there are new posts coming up almost every 15 seconds which make them go on top(by top I literally mean the first row) of the resultset(I do not want to display these latest posts in the second or third pages but they alter the resultset size so I cannot use LIMIT 10,10 for the 2nd page and so on as the posts will be repeated.).
Now, all I know is the last ID of the post that I displayed. Say 21 here. So, I want to display the posts of IDs 23,4,32,58,61,43 (refer to the resultset table above). Now, do I load all the rows without using the LIMIT clause and display 10 ids occurring after the id 21. But for that I will have to interate over thousands of useless rows.But, I cannot use a LIMIT clause for the 2nd,3rd... pages that is for sure. Also, the IDs are jumbled, so I can definitely not use WHERE ID>.... So, where do we go now?
I'm not sure if I've understood your question correctly, but here's how I think I would do it:
Add a timestamp column to your table, let's call it date_added
When displaying the first page, use your query as-is (with LIMIT 10) and hang on to the timestamp of the most recent record; let's call it last_date_added.
For the 2nd, 3rd and subsequent pages, modify your query to filter out all records with date_added > last_date_added, and use LIMIT 10, 10, LIMIT 20, 10, LIMIT 30, 10 and so on.
This will have the effect of freezing your resultset in time, and resetting it every time the first page is accessed.
Notes:
Depending on the ordering of your resultset, you might need a separate query to obtain the last_date_added. Alternatively, you could just cut off at the current time, i.e. the time when the first page was accessed.
If your IDs are sequential, you could use the same trick with the ID.
Hmm..
I thought for a while and came up with 2 solutions. :-
To store the Ids of the post already displayed and query WHERE ID NOT IN(id1,id2,...). But, that would cost you extra memory. And if the user loads 100 pages and the ids are in 100000s then a single GET request would not be able to handle it. At least not in all browsers. A POST request can be used.
Alter the way you display posts from COL1. I don't know if this would be a good way for you. But, it can save you bandwith and make your code cleaner. It may also be a better way. I would suggest this :- SELECT * from TABLE where COL1 IS NOT NULL AND COL2 IS NULL AND Id>.. ORDER BY ID DESC LIMIT 10,10. This can affect the way you display your posts by leaps and bounds. But, as you said in your comments that you check if a post meets a criteria and change the COL1 from NULL to the current timestammp, I guess that the newer the posts the, the more above you want to display them. It's just an idea.
I assume new posts will be added with a higher ID than the current max ID right? So couldn't you just run your query and grab the current max ID. Then when you query for page 2 do the same query but with "ID < max_id". This should give you the same result set as your page 1 query because any new rows will have ID > max_id. Hope that helps?
How about?
ORDER BY `COL1`,`ID`;
This would always put IDs in order. This will let you use:
LIMIT 10,10
for your second page.

MySQL Empty Cells In Normalised Table

OK, Last post on this subject (I hope). I've been trying to look into normalisation for tables in a website that I've been building and I have to be honest that I've struggled with it, however after my last post it seems that I may have finally grasped it and set my tables properly.
However, one question remains. If I create a table that is seemingly in 3rd normal form, is it acceptable to have areas of white space or empty cells if the data is relevant to that specific table? Let me give you an example:
On a news website I have an Authors_Table
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
| ID | FIRSTNAME | SURNAME | EMAIL | BIO ( REQUIRED ) | TWITTER | FACEBOOK | WEBSITE |
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
| 01 | Brian | Griffin | brian#gmail.com | About me... | URL | | URL |
| 02 | Meg | Griffin | meg#gmail.com | About me... | URL | | |
| 03 | Peter | Griffin | peter#gmail.com | About me... | | URL | URL |
| 04 | Glen | Quagmire | glen#gmail.com | About me... | URL | URL | |
+----+-----------+----------+-----------------+-------------------+---------+----------+---------+
This would be used on the article page to give a little details about who has written it, which is very common in newspapers and on modern blogs. Now the last 3 columns Facebook, Twitter, Website are obviously relevant to the Author & therefore to the PK (ID). As you know though, not everyone has either twitter or a wesbite or facebook so the content of these cells is rather flexible so obviously empty cells will occur in some cases.
It was suggested to do it another way so I produced:
Links
+----+-------------------+
| ID | TYPE |
+----+-------------------+
| 01 | Facebook |
| 02 | Twitter |
| 03 | Website |
+----+-------------------+
Author_Links
+----------+--------+------+
| AUTHOR | TYPE | LINK |
+----------+--------+------+
| 01 | 01 | URL |
| 01 | 02 | URL |
| 01 | 03 | URL |
| 02 | 02 | URL |
| 02 | 03 | URL |
| 03 | 01 | URL |
+----------+--------+------+
Now I understand the concept of this however isn't it just as "correct" to have and to use the original table. Updates can be made using a form & php to say:
$update_link_sql = "UPDATE authours SET facebook = ' NEW VALUE ' WHERE id = '$author_id'";
$update_link_res = mysqli_query($con, $update_links_sql);
As for me Authors_Table is correct.
| ID | FIRSTNAME | SURNAME | EMAIL | BIO ( REQUIRED ) | TWITTER | FACEBOOK | WEBSITE |
The only reason to have three tables:
Authors
| ID | FIRSTNAME | SURNAME | EMAIL | BIO ( REQUIRED ) |
Link_types
| ID | TYPE |
Author_links
| AUTHOR_ID | LINK_TYPE_ID | URL |
...is that your authors could have more than one link of specific type (for example two twitter accounts, btw, is it legal?)
If we suppose that any author can have no more than one account of each type - your version with single table is correct.
Either way is acceptable depending on functional requirements.
If you need to dynamically add more url types/fields to profile then use latter.
If there is ever going to be only 3 then former is better.
No need to over-engineer.
Yes, it's "correct" to store "optional" attributes as columns in the entity table. It's just when we have repeated values, e.g. multiple facebook pages for an author, for example, that we'd want to implement the child table. (We don't want to store "repeating" attributes in the entity table.)
As long as there's a restriction in the model, that an attribute will be limited to a single value (a single facebook page, a single twitter, etc.) those attributes can be stored in the entity table. We'd just use a NULL value to indicate that a value is not present.
One benefit of the separate table approach (outlined in your post) is that it would be "easier" to add a new "type" of URL. For example, if in the future we want to store a blogspot URL, or an instagram URL, instead of having to modify the entity table to add new columns, we can simply add rows to the "link_type" table and "author_link" table. That's the big benefit there.

Datatables Serverside Processing with Column Filterting using Multiple Tables

I'm displaying a record set using Datatables pulling records from two tables.
Table A
sno | item_id | start_date | end_date | created_on |
===========================================================
10523563 | 2 | 2013-10-24 | 2013-10-27 | 2013-01-22 |
10535677 | 25 | 2013-11-18 | 2013-11-29 | 2013-01-22 |
10587723 | 11 | 2013-05-04 | 2013-05-24 | 2013-01-22 |
10598734 | 5 | 2013-06-14 | 2013-06-22 | 2013-01-22 |
Table B
id | item_name |
=====================================
2 | Timesheet testing |
25 | Vigour |
11 | Fabwash |
5 | Cruise |
Now since the number of records returned is going to turn into a big number in near future, I want the processing to be done serverside. I've successfully managed to achieve that but it came at a cost. I'm running into a problem while dealing with filters.
From the figure above, (1) is the column whose value will be in int (item_id), but using some small modifications inside the while loop of the mysql resource, I'm displaying the corresponding string using Table B.
Now if I use the filter (2), it is working fine since those values come from Table A
The Problem
When I try to filter from the field (3), if I enter a string value such as fab it says no record found. But if I enter an int such as 11 I get a single row which contains Fabwash as the item name.
So while filtering I'm required to use the direct value used in Table A and not its corresponding string value stored in Table B. I hope the point that I'm putting across is understandable because it is hard to explain it in words.
I'm clueless on how to solve the issue.

Categories