好的,首先我有不可变的值:
4 8 16 32 64 128 256
我有一张类似的表:
+----+------+---------------------+-------------+
| id | full_name | club_name | y_of_birth |
+----+------+---------------------+-------------+
| 1 | Ahmed Sayed | El Ahly | 2000 |
+----+------+---------------------+-------------+
| 2 | Kareem Gaber | El Ahly | 2000 |
+----+------+---------------------+-------------+
| 3 | Maher Zein | El Ahly | 2003 |
+----+------+---------------------+-------------+
| 4 | Mohab Saeed | El Ahly | 2003 |
+----+------+---------------------+-------------+
| 5 | Kamal saber | wadi dgla | 2000 |
+----+------+---------------------+-------------+
| 6 | gamel kamel | el-nasr | 2002 |
+----+------+---------------------+-------------+
| 7 | omar galal | Cocorico | 2000 |
+----+------+---------------------+-------------+
| 8 | Kamal saber | Cocorico | 2004 |
+----+------+---------------------+-------------+
| 9 | Mohamed gad | Ismaily | 2000 |
+----+------+---------------------+-------------+
| 10 | ehab zeyad | Ismaily | 2005 |
+----+------+---------------------+-------------+
| 11 | moaz maged | Smouha | 2001 |
+----+------+---------------------+-------------+
| 12 | mazen mahmod | elmasry | 2006 |
+----+------+---------------------+-------------+
| 13 | ahmed shawky | Petroget | 2002 |
+----+------+---------------------+-------------+
| 14 | shaker ali | Petroget | 2007 |
+----+------+---------------------+-------------+
我尝试使用查询来过滤数据库中的数据
select full_name,club_name from players where y_of_birth=2000
结果是5
玩家应该是这样的:
+--------------+--------------+
| full_name | club_name |
+--------------+--------------+
| Ahmed Sayed | El Ahly |
+----+------+--+--------------+
| Kareem Gaber | El Ahly |
+------+-------+--------------+
| Kamal saber | wadi dgla |
+------+-------+--------------+
| omar galal | Cocorico |
+------+-------+--------------+
| Mohamed gad | Ismaily |
+------+-------+--------------+
好的条件是:
如果结果超过 4 > 4
且 <8> <= 8
将结果放入8
我们的案例中结果是5
它意味着8 - 5 = 3
意味着迭代这个单词3次,结果应该是这样的:
+--------------+-------------+
| full_name | club_name |
+--------------+-------------+
| Ahmed Sayed | El Ahly |
+----+------+--+-------------+
| **ANY WORD** | |
+--------------+-------------+
| Kareem Gaber | El Ahly |
+------+-------+-------------+
| Kamal saber | wadi dgla |
+------+-------+-------------+
| **ANY WORD** | |
+--------------+-------------+
| omar galal | Cocorico |
+------+-------+-------------+
| Mohamed gad | Ismaily |
+------+-------+-------------+
| **ANY WORD** | |
+--------------+-------------+
注意:请不要在**ANY WORD**
与上述示例之间相邻:
+------+-------+
| **ANY WORD** |
+--------------+
| **ANY WORD** |
+--------------+
或
club_name
与上述示例之间没有相邻:
+------+-------+
| El Ahly |
+--------------+
| El Ahly |
+--------------+
已更新:
再次举例
基于这些数字
4 8 16 32 64 128 256
并且条件是:
4
和&gt; 2
表示(4 - the number of query result)
示例:如果查询结果为3
,那么4 - 3 = 1
因此1
是**ANY WORD**
的数字,所以所需的输出就像那个:
+--------------+-------------+
| full_name | club_name |
+--------------+-------------+
| Ahmed Sayed | El Ahly |
+----+------+--+-------------+
| **ANY WORD** | |
+--------------+-------------+
| Kareem Gaber | El Ahly |
+------+-------+-------------+
| Kamal saber | wadi dgla |
+--------------+-------------+
8
如果查询结果&lt; = 8
和&gt; 4
表示(8 - the number of query result)
例如:
查询结果为5
所以8 - 5 = 3
因此3
是**ANY WORD**
的数字,因此所需的输出将是那样的
+--------------+-------------+
| full_name | club_name |
+--------------+-------------+
| Ahmed Sayed | El Ahly |
+----+------+--+-------------+
| **ANY WORD** | |
+--------------+-------------+
| Kareem Gaber | El Ahly |
+------+-------+-------------+
| Kamal saber | wadi dgla |
+------+-------+-------------+
| **ANY WORD** | |
+--------------+-------------+
| omar galal | Cocorico |
+------+-------+-------------+
| Mohamed gad | Ismaily |
+------+-------+-------------+
| **ANY WORD** | |
+--------------+-------------+
依旧使用4
和16
以及32
和64
..等到256
。
非常感谢任何帮助。
答案 0 :(得分:3)
使用变量并使用来自here的基本相同技巧的新增和改进(第3版):
SELECT
IF(is_real, '**ANY WORD**', full_name) AS full_name,
IF(is_real, '', club_name) AS club_name
FROM
(
SELECT
full_name,
club_name,
(@row_num2:= @row_num2 + 1) AS row_num
FROM
(
SELECT p3.*
FROM
(
SELECT
p2.*,
(@row_num := @row_num + 1) AS row_num
FROM
(
SELECT *
FROM players AS p1
WHERE y_of_birth = 2000
) AS p2
CROSS JOIN
(
SELECT
@row_num := 0,
@count := (SELECT COUNT(*) FROM players WHERE y_of_birth = 2000)
) AS vars
ORDER BY club_name
) AS p3
ORDER BY row_num % FLOOR(@row_num / 2), row_num
) AS p4
CROSS JOIN
(
SELECT
@row_num2 := -1,
@extra := GREATEST(2, POW(2, CEIL(LOG2(@count)))) - @count) AS vars
) AS data
LEFT JOIN
(
(SELECT 1 AS is_real)
UNION ALL
(SELECT 0 AS is_real)
) AS filler
ON
MOD(row_num, FLOOR(@count / @extra)) = 0 AND
row_num / FLOOR(@count / @extra) < @extra
ORDER BY row_num, is_real
对于您提供的示例数据,这会产生如下内容:
+--------------+-----------+
| full_name | club_name |
+--------------+-----------+
| Ahmed Sayed | El Ahly |
| **ANY WORD** | |
| Mohamed gad | Ismaily |
| **ANY WORD** | |
| omar galal | Cocorico |
| **ANY WORD** | |
| Kareem Gaber | El Ahly |
| Kamal saber | wadi dgla |
+--------------+-----------+
这适用于任何规模的结果;只需将条件(y_of_birth = 2000
)更改为您想要的任何条件。我升级到MySQL 5.6来测试它(实际上它实际上产生了一些小的差异)。
基本技巧是使用1
然后0
创建一个包含静态值的两行表(在本例中为UNION
和LEFT JOIN
)实际结果需要多次填充2的幂。这意味着我们已经计算了结果中每一行的数量(称为row_num
),这样我们就可以正确地形成连接条件。最后,每隔这么多行产生一个重复的行;最后一点是通过检查我们是在真实的还是假的(IF
或1
)行来更改我们在这些重复项上选择的内容(使用0
)。
这可以防止同一支球队的球员彼此相邻,除非这是不可能的,因为一支球队的球员太多;请参阅上面的链接,了解有关如何操作的更多信息。基本的想法是通过俱乐部订购,然后从该列表的上半部分和后半部分进行备选。
最后的诀窍是弄清楚虚拟行中加入的数量和位置。在尝试了几件事之后,我意识到这实际上非常简单:只需连接每一行,直到达到所需数量的虚拟行(@extra
)。但是,这会将所有虚拟行打包在结果的顶部;更广泛地传播它们(不是完全展开,而是更加分散),计算我们需要多少次添加一个(FLOOR(@count / @extra)
),然后每隔多行放一个({{1}的第一部分)条件)直到添加足够的(第二部分)。
答案 1 :(得分:2)
以下过程将返回4列。应显示第一列和第二列。第三列只是应该忽略的rownum。如果第四列不是空白,则在下一行显示,否则不显示。
DELIMITER //
create procedure test()
BEGIN
declare N int;
declare X int;
select count(*) from players where y_of_birth=2000 into N;
set X = power(2,ceil(log2(N))) -N;
SELECT full_name, club_name, @row := @row + 1 AS row,
case when (@row<= X)
then 'any word' else '' end r
FROM players, (SELECT @row:=0) z
where y_of_birth=2000;
END //
DELIMITER
call test;