post's category (forum) in xf_post (xenforo) - xenforo

I want to display all posts from all threads from one category (forum) but:
xf_post http://screenshu.com/static/uploads/temporary/c8/xy/5d/zia0a4.jpg
as you can see, there is no cell for category (forum). I just want to know If I can get it from other table?

On Database:
xf_node: all nodes (category , forum , page , ect) with : node_id , parent_node , ...
xf_thread: all threads with: thread_id , node_id
post_id (xf_post) --> thread_id (xf_post , xf_thread) --> node_id (xf_thread , xf_node).
or
node_id(xf_thread , xf_node) --> thread_id (xf_post , xf_thread) --> post_id (xf_post)

Related

MySQL hierarchical recursive query

I have a MySQL table which is as follows:
NCBI_TAXON_ID PARENT_ID TAXON_NAME TAXON_STRAIN RANK
1 1 root no rank
2759 131567 Eukaryota superkingdom
6072 33208 Eumetazoa no rank
7711 33511 Chordata phylum
7742 89593 Vertebrata no rank
7776 7742 Gnathostomata no rank
8287 117571 Sarcopterygii no rank
9347 32525 Eutheria no rank
9443 314146 Primates order
9526 314293 Catarrhini parvorder
9604 314295 Hominidae family
9605 207598 Homo genus
9606 9605 Homo sapiens species
32523 1338369 Tetrapoda no rank
32524 32523 Amniota no rank
32525 40674 Theria no rank
33154 2759 Opisthokonta no rank
33208 33154 Metazoa kingdom
33213 6072 Bilateria no rank
33511 33213 Deuterostomia no rank
40674 32524 Mammalia class
89593 7711 Craniata subphylum
117570 7776 Teleostomi no rank
117571 117570 Euteleostomi no rank
131567 1 cellular organisms no rank
207598 9604 Homininae subfamily
314146 1437010 Euarchontoglires superorder
314293 376913 Simiiformes infraorder
314295 9526 Hominoidea superfamily
376913 9443 Haplorrhini suborder
The above data is in the hierarchical model. For example, if I want to find the hierarchy of 'Homo Sapiens'. it linked via PARENT_ID i.e. 9605 etc.
NCBI_TAXON_ID PARENT_ID TAXON_NAME TAXON_STRAIN RANK
9606 9605 Homo sapiens species
9605 207598 Homo genus
207598 9604 Homininae subfamily
.
.
.
1 1 root no rank
Hope I able to explain the data model properly.
Now I want to retrieve the all the hierarchy by providing the taxon_name i.e 'Homo Sapiens' and in the hierarchical order.
Is it possible to do in MySQL?
Help needed.
Recursive CTEs (WITH RECURSIVE) were introduced in MySQL 8.0 (and MariaDB 10.2.2). Using such an expression, you can achieve what you want quite easily:
WITH RECURSIVE ancestors AS (
SELECT * FROM taxonomy
WHERE taxon_name = #desired_taxon
UNION DISTINCT
SELECT t.* FROM
taxonomy AS t,
ancestors AS a
WHERE t.ncbi_taxon_id = a.parent_id
) SELECT * FROM ancestors;
The use of UNION DISTINCT rather than UNION [ALL] is necessary to avoid an infinite loop once we reach the root record. If you're okay with not having the root record in the result set, or you just don't want it, then you can use the following instead:
WITH RECURSIVE ancestors AS (
SELECT * FROM taxonomy
WHERE taxon_name = #desired_taxon
UNION
SELECT t.* FROM
taxonomy AS t,
ancestors AS a
WHERE
t.ncbi_taxon_id = a.parent_id
AND t.ncbi_taxon_id != 1
) SELECT * FROM ancestors;
Additionally, it appears that records in your dataset have rank = 'no rank' if and only if taxon_strain = '' (or taxon_strain is NULL). If this is the case, then your database schema could be simplified by removing the rank column and inferring this value from whether taxon_strain is defined. Also, parent_id should reference ncbi_taxon_id, and arguably, the parent_id of the root record should be NULL — this would also allow your recursive query to not need UNION DISTINCT if you want the root record to appear in the result set.
In particular, here is the schema I would use:
CREATE TABLE taxonomy (
id INTEGER UNSIGNED PRIMARY KEY,
parent_id INTEGER UNSIGNED,
name VARCHAR(32),
strain VARCHAR(32),
FOREIGN KEY (parent_id) REFERENCES taxonomy (id)
);
INSERT INTO taxonomy VALUES
(1 , NULL , 'root' , NULL ),
(131567 , 1 , 'cellular organisms' , NULL ),
(2759 , 131567 , 'Eukaryota' , 'superkingdom' ),
(33154 , 2759 , 'Opisthokonta' , NULL ),
(33208 , 33154 , 'Metazoa' , 'kingdom' ),
(6072 , 33208 , 'Eumetazoa' , NULL ),
(33213 , 6072 , 'Bilateria' , NULL ),
(33511 , 33213 , 'Deuterostomia' , NULL ),
(7711 , 33511 , 'Chordata' , 'phylum' ),
(89593 , 7711 , 'Craniata' , 'subphylum' ),
(7742 , 89593 , 'Vertebrata' , NULL ),
(7776 , 7742 , 'Gnathostomata' , NULL ),
(117570 , 7776 , 'Teleostomi' , NULL ),
(117571 , 117570 , 'Euteleostomi' , NULL ),
(8287 , 117571 , 'Sarcopterygii' , NULL ),
.
.
.
( ... );
Then your recursive query can be the following:
WITH RECURSIVE ancestors AS (
SELECT * FROM taxonomy
WHERE name = #desired_taxon
UNION
SELECT t.* FROM
taxonomy AS t,
ancestors AS a
WHERE t.id = a.parent_id
) SELECT * FROM ancestors;
Such a query is guaranteed to terminate at a row where parent_id is NULL, since this is never equal to id for any other row, since, as a primary key, id must not be NULL.

Separately ordering two queries and then joining them

I am designing a comment system where users first see their comments (newest first) and then any other users comments (newest first). So in the end it would look like:
My Comment 1 (Dec 3)
My Comment 2 (Dec 2)
My Comment 3 (Dec 1)
Not My Comment 1 (Dec 5)
Not My Comment 2 (Dec 4)
Not My Comment 3 (Dec 3)
So to pull the info from the table I have:
SELECT * FROM ( SELECT * FROM testTable WHERE me='1' ORDER BY `lastReply` DESC ) DUMMY1
UNION
SELECT * FROM (SELECT * FROM testTable ORDER BY `lastReply` DESC) DUMMY2
This does what I want only instead of ordering by lastReply descending (so the users newest comment is first) it instead orders by lastReply ascending (so the users oldest comment is first).
For the life of me I can't figure out why this is happening. Any advice?
You can view a simplified version of the table here:
mysqli_query($con," CREATE TABLE testTable( text varchar(255), me varchar(255), lastReply varchar(255) ) ");
mysqli_query($con,"INSERT INTO testTable (text, me , lastReply) VALUES ('A',1,3),('E',0,2),('C',1,1) , ('D',0,1) , ('B',1,2) ,('F',0,3) ");
echo '<table border="1">';
while($arrayrow = mysqli_fetch_array($result)) {
echo '<tr><td>'.$arrayrow['text'].'</td><td>'.$arrayrow['me'].'</td><td>'.$arrayrow['lastReply'].'</td></tr>';
};
echo '</table>';
SELECT * from (
SELECT *,0 as sort_order FROM table WHERE IP='userIP'
UNION
SELECT *,1 as sort_order FROM table WHERE IP <>'userIP'
)tmp
ORDER by sort_order asc, lastReply Desc

How to extract two rows for each unique user id

Following query used to extract the following column & rows.
issue is i am not able extract two rows from each user ID .
If i am using limit then fetches only 1st two rows.
so how i can extract the two rows for each Unique user id.
For example :
two rows of userid 222
two rows of userid 122
two rows of userid 367
and so on
TEXT OP :
Expected output :
Assuming id is your user id and post_ID is unique.
(SELECT id,name,post,Image,post
FROM users
GROUP BY id
ORDER BY id
)
UNION
(SELECT id,name,post,Image,post
FROM users
WHERE post_ID NOT IN
(SELECT post_ID
FROM users
GROUP BY id
ORDER BY id)
GROUP BY id
ORDER BY id
)
ORDER BY id, post_ID
Please check my query from which I get the below answer:
(
SELECT store_id, `key_id` , `string` , `translate` , `locale`
FROM `core_translate` AS C
GROUP BY `store_id`
ORDER BY `store_id`
)
UNION (
SELECT store_id, `key_id` , `string` , `translate` , `locale`
FROM `core_translate` AS C
WHERE `key_id` NOT
IN (
SELECT `key_id`
FROM `core_translate` AS C
GROUP BY `store_id`
ORDER BY `store_id`
)
GROUP BY `store_id`
ORDER BY C.`store_id`
)
ORDER BY store_id, `key_id`
store_id key_id string translate locale
0 20 Screensize Screensize en_US
0 21 Gender Gender en_US
1 1 Size Size en_US
1 2 Color Color en_US
2 5 Large Image Large Image en_US
2 6 Medium Image Medium Image en_US
3 10 Manufacturer Manufacturer en_US
3 11 Dimensions Dimensions en_US
4 15 Description Description en_US
4 16 Weight Weight en_US
Not sure this is workable on mysql, but you can this.
I'm assuming id is user id and post_ID is unique.
EDIT
try to workaround mysql limitation.
select id,name,post_Imagename_small,Image_title,post_ID from users u1
where u1.post_ID in (
select u3.post_ID from (
select u2.post_ID from users u2
where u2.id = u1.id
limit 2
) s u3
)
order by u1.id
EDIT 2
in the case that the answer doesn't work, here is a good reading on this sort of querying problem, there're various solving approachs too.

MySql query with multiple counts in result

I have a tables
create table posts (
text varchar(20),
created_at datetime,
user_id integer
);
create table users (
id integer,
name varchar(20),
important bolean
);
create table categories (
id integer,
name varchar(20),
);
create table categories_posts (
category_id integer,
post_id integer
);
Want to calculate the number of posts for each category between certain times with results like this
START_TIME_PERIOD, category, count_all, count_important, count_normal
'2013-03-06 23:40', 'dogs', 20, 5, 15
'2013-03-06 23:40', 'cats', 22, 6, 16
'2013-03-06 23:40', 'birds', 24, 7, 17
where the importance is based on the users importance.
To get one count e.g. important
select '2013-03-06 23:40', categories.name, count(*)
from posts, users, categories
where posts.id = categories_posts.post_id
and categories.id = categories_posts.category_id
and posts.user_id = users.id
and users.important = true
and posts.created_at BETWEEN '2013-03-06 23:40' AND '2013-03-06 23:20'
group by 1, 2
What is the best way to get the three counts in a single result set?
Thanks
SELECT ..... , count(*), SUM(IF(user.important,1,0)) as count_important, COUNT(*) - SUM(IF(user.important,1,0)) as count_normal
Rather than using COUNT, you can use SUM combined with CASE, e.g.
SELECT COUNT(*) AS count_all,
SUM(CASE WHEN important = 1 THEN 1 ELSE 0 END) AS count_important

How to update from select within 1 table?

I have a news table where each record have fields:
news_id (INT), parent_id (INT) , subitems (INT)
I want each record to carry the total (count) of direct children of it
e.g. (I want the result to be like that)
news_id: 1, parent_id: 0, subitems: 2
news_id: 2, parent_id: 1 , subitems: 0
news_id: 3, parent_id: 1 , subitems: 0
How do I do something like this correctly:
UPDATE news n
SET subitems = (SELECT COUNT(*) FROM `news` AS `n2`
WHERE `n2`.`parent_id` = `n`.`news_id`)
as the above gives the following error:
#1093 - You can't specify target table 'n' for update in FROM clause
This is how I solved it:
Notice: this is UGLY for performance, it's ok to do it just once but not for an ongoing operation
UPDATE news n
SET subitems = (SELECT COUNT(*)
FROM (SELECT parent_id FROM `news` AS `n2`
WHERE `n2`.`parent_id` <> '0') AS n3 WHERE n3.parent_id = n.news_id)
WHERE n.parent_id = '0'