Avatar billede SommerFyr Seniormester
05. marts 2024 - 21:45 Der er 11 kommentarer og
1 løsning

søgning mellem to set variable..

Hej

jeg er ved at lave et database hvor jeg har to ens felter der er set format.
SET('A','B','C') eks

min table
CREATE TABLE `test` (
  `userid` int(11) NOT NULL,
  `usergrup` set('A','B','C','D') NOT NULL,
  `username` varchar(160) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

min sql
SELECT `test`.* FROM `test` INNER JOIN `test` as myuser on `test`.`userid`<>myuser.userid WHERE myuser.userid='1'

Her vil jeg så gerne have at min bruger som er medlem af A,B
kan finde alle der også er i de gruppe men ikke C,D men også medlemmer af A,D bruger..

Håber det giver mening..
Avatar billede arne_v Ekspert
05. marts 2024 - 22:20 #1
... WHERE usergrup IN ('A','B')

?
Avatar billede arne_v Ekspert
05. marts 2024 - 22:21 #2
Spørgsmålet uvedkommende men man anbefaler InnoDB fremfor MyISAM idag som engine.
Avatar billede SommerFyr Seniormester
05. marts 2024 - 22:44 #3
Hej arne..

første spørsmål

jeg skal bruge den i denne her
SELECT `test`.* FROM `test` INNER JOIN `test` as myuser on `test`.`userid`<>myuser.userid and ( her skal den rette ) WHERE myuser.userid='1'

sådan at når jeg søger med myuser.userid så henter den usergrup og checker i test usergrup for om gruper macher..

Det anden hvorfor InnoDB frem for MyISAM ??
Avatar billede SommerFyr Seniormester
05. marts 2024 - 22:48 #4
jeg har prøve med denne her SELECT `test`.* FROM `test` INNER JOIN `test` as myuser on `test`.`userid`<>myuser.userid and (`test`.`usergrup`) IN (myuser.usergrup) WHERE myuser.userid='1' men det virker ikke
Avatar billede arne_v Ekspert
05. marts 2024 - 23:44 #5
Lidt manual kigning siger at:

... WHERE FIND_IN_SET('A', usergrup)

er legal, men dit problem er vist mere komplekst.

Men jeg har stadig ikke forstået hvad du vil. Kan du vise et eksempel med nogle data?
Avatar billede arne_v Ekspert
05. marts 2024 - 23:44 #6
InnoDB tabeller understøtter transaktioner. MyISAM tabeller gør ikke,
Avatar billede SommerFyr Seniormester
06. marts 2024 - 02:10 #7
Det kan du tro arne..

jeg er ved at lave et medlems side hvor folk kan være tilknytte grupper
og når man så er logge ind skal man kun kun finde dem der er i ens egen gruppe som ens selv..

eks har vi user 1 der er medlem i a,b,c,d den bruger skal kun finde alle der er i et af de give gruper.

mens user 2 som kun er i grupe b skal kun finde folk der er i gruppe b.

user1, a,b,c,d
user2, a
user3, b
user4, c
user5, d
user6, a,d
user7, a,c

søger vi med user1 får vi = user1,user2,user3,user4,user5,user6,user7
søger vi med user2 får vi kun user1,user6,user7
søger vi med user3 får vi kun user1,user3
søger vi med user4 får vi kun user1,user4,user7
søger vi med user5 får vi kun user1,user5,user6
søger vi med user6 får vi kun user1,user2,user5,user6,user7
søger vi med user7 får vi kun user1,user2,user4,user6,user7

jeg håber det giver mening.

jeg kender godt FIND_IN_SET men den kan du kun søge hvis det er en og set ikke set i set.
Avatar billede arne_v Ekspert
06. marts 2024 - 02:31 #8
Lidt læsen i MySQL manual for mig til at foreslå:

... WHERE ... (((u1.usergrup + 0) & (u2.usergrup + 0)) <> 0)

hvilket ser kryptisk ud, men burde returnere true med overlap of false uden overlap.
Avatar billede SommerFyr Seniormester
06. marts 2024 - 08:19 #9
Fedt det ser ud til at virker. den tro jeg sku ikke jeg selv have fundet.. hvad er det for en manual du taler om ?
Avatar billede SommerFyr Seniormester
06. marts 2024 - 08:20 #10
min kode kommer til at se sådan ud..

SELECT `test`.* FROM `test` INNER JOIN `test` as myuser on `test`.`userid`<>myuser.userid and (((`test`.usergrup + 0) & (myuser.usergrup + 0)) <> 0) WHERE myuser.userid='5';
Avatar billede arne_v Ekspert
06. marts 2024 - 16:21 #11
Det er ogs[ en lidt obskur løsning.

Manalen er:

https://dev.mysql.com/doc/refman/8.0/en/set.html

hvor +0 tricket beskrives.

Så skal man naturligvis forstå binær AND.

Her er en demo:

mysql> CREATE TABLE u (
    ->    name VARCHAR(32),
    ->    grps SET ('A','B','C','D'),
    ->    PRIMARY KEY(name)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO u VALUES('Anders', 'A,B');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO u VALUES('Børge', 'B,C');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO u VALUES('Christian', 'D');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT name,grps FROM u;
+-----------+------+
| name      | grps |
+-----------+------+
| Anders    | A,B  |
| Børge    | B,C  |
| Christian | D    |
+-----------+------+
3 rows in set (0.00 sec)

mysql> SELECT name,(grps+0) FROM u;
+-----------+----------+
| name      | (grps+0) |
+-----------+----------+
| Anders    |        3 |
| Børge    |        6 |
| Christian |        8 |
+-----------+----------+
3 rows in set (0.00 sec)

mysql> SELECT u1.name,u1.grps,(u1.grps+0),u2.name,u2.grps,(u2.grps+0),((u1.grps+0) & (u2.grps+0))
    -> FROM u u1 JOIN u u2 ON u1.name <> u2.name;
+-----------+------+-------------+-----------+------+-------------+-----------------------------+
| name      | grps | (u1.grps+0) | name      | grps | (u2.grps+0) | ((u1.grps+0) & (u2.grps+0)) |
+-----------+------+-------------+-----------+------+-------------+-----------------------------+
| Christian | D    |          8 | Anders    | A,B  |          3 |                          0 |
| Børge    | B,C  |          6 | Anders    | A,B  |          3 |                          2 |
| Christian | D    |          8 | Børge    | B,C  |          6 |                          0 |
| Anders    | A,B  |          3 | Børge    | B,C  |          6 |                          2 |
| Børge    | B,C  |          6 | Christian | D    |          8 |                          0 |
| Anders    | A,B  |          3 | Christian | D    |          8 |                          0 |
+-----------+------+-------------+-----------+------+-------------+-----------------------------+
6 rows in set (0.00 sec)

mysql> DROP TABLE u;
Query OK, 0 rows affected (0.01 sec)
Avatar billede arne_v Ekspert
06. marts 2024 - 16:41 #12
Tilsvarende C# kode (med output både i decimal og binary):


using System;
using System.Collections.Generic;

namespace SetFun
{
    public class User
    {
        public const int GROUP_A = 0x00000001;
        public const int GROUP_B = 0x00000002;
        public const int GROUP_C = 0x00000004;
        public const int GROUP_D = 0x00000008;
        public string Name { get; set; }
        public int Grps { get; set; }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            List<User> u = new List<User>();
            u.Add(new User { Name = "Anders", Grps = User.GROUP_A | User.GROUP_B });
            u.Add(new User { Name = "Børge", Grps = User.GROUP_B | User.GROUP_C });
            u.Add(new User { Name = "Christian", Grps = User.GROUP_D });
            foreach(User u1 in u)
            {
                foreach(User u2 in u)
                {
                    if(u1.Name != u2.Name)
                    {
                        Console.WriteLine("{0,-10} {1,8} {2,-10} {3,8} {4,8}", u1.Name,
                                                                                u1.Grps,
                                                                                u2.Name,
                                                                                u2.Grps,
                                                                                u1.Grps & u2.Grps);
                    }
                }
            }
            foreach(User u1 in u)
            {
                foreach(User u2 in u)
                {
                    if(u1.Name != u2.Name)
                    {
                        Console.WriteLine("{0,-10} {1,8} {2,-10} {3,8} {4,8}", u1.Name,
                                                                              Convert.ToString(u1.Grps, 2).PadLeft(8, '0'),
                                                                              u2.Name,
                                                                              Convert.ToString(u2.Grps, 2).PadLeft(8, '0'),
                                                                              Convert.ToString(u1.Grps & u2.Grps, 2).PadLeft(8, '0'));
                    }
                }
            }
            Console.ReadKey();
        }
    }
}



Anders            3 Borge            6        2
Anders            3 Christian        8        0
Borge            6 Anders            3        2
Borge            6 Christian        8        0
Christian        8 Anders            3        0
Christian        8 Borge            6        0
Anders    00000011 Borge      00000110 00000010
Anders    00000011 Christian  00001000 00000000
Borge      00000110 Anders    00000011 00000010
Borge      00000110 Christian  00001000 00000000
Christian  00001000 Anders    00000011 00000000
Christian  00001000 Borge      00000110 00000000
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester