Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 编写引用同一表两次的SQL查询_Python_Sqlite_Database Design_Orm_Sqlalchemy - Fatal编程技术网

Python 编写引用同一表两次的SQL查询

Python 编写引用同一表两次的SQL查询,python,sqlite,database-design,orm,sqlalchemy,Python,Sqlite,Database Design,Orm,Sqlalchemy,考虑下表中的定义 class MCastSession(Base): __tablename__ = 'mcast_session' id = Column(Integer, primary_key=True) ip = Column(Integer) port = Column(Integer) __table_args__ = ( UniqueConstraint('ip', 'port'), ) class Topic(Base): __tablename__ =

考虑下表中的定义

class MCastSession(Base):
  __tablename__ = 'mcast_session'
  id = Column(Integer, primary_key=True)
  ip = Column(Integer)
  port = Column(Integer)
  __table_args__ = ( UniqueConstraint('ip', 'port'), )

class Topic(Base):
  __tablename__ = 'topic'
  id = Column(Integer, primary_key=True)
  name = Column(String, unique=True)
  mcast_session_id = Column(Integer, ForeignKey('mcast_session.id'))
  mcast_session = relationship('MCastSession')

class Host(Base):
  __tablename__ = 'host'
  id = Column(Integer, primary_key=True)
  name = Column(String, unique=True)

class Subscriber(Base):
  __tablename__ = 'subscriber'
  id = Column(Integer, primary_key=True)
  topic_id = Column(Integer, ForeignKey('topic.id'))
  topic = relationship('Topic')
  host_id = Column(Integer, ForeignKey('host.id'))
  host = relationship('Host')
  __table_args__ = ( UniqueConstraint('topic_id', 'host_id'), )

Example data:
Topic Session
T1    IP1:port1
T2    IP1:port2
T3    IP1:port2
T4    IP2:port1

Topic Host
T1    H1
T2    H1
T4    H2

我想编写一个查询,以获取订阅多播ip但不处理ip的所有主题的所有主机。在上面的例子中。H1有T1,因此订阅IP1,但没有T3,也有相同的IP1。因此查询应该返回H1。H2处理其订阅的IP(T4)的所有主题(T4),因此H2不应出现在结果中。如何为上述内容编写查询

下面的查询将生成目标:

select distinct host1.name host_name
  from Subscriber Subscriber1
 inner join host host1
    on host1.id = Subscriber1.Host_Id
 inner join topic topic1
    on topic1.id = Subscriber1.Topic_Id
 inner join mcast_session mcast_session1
    on mcast_session1.id = topic1.mcast_session_id
 where (select count(*)
          from mcast_session
         where mcast_session.ip = mcast_session1.ip) !=
       (select count(*)
          from topic
         inner join mcast_session
            on topic.mcast_session_id = mcast_session.id
         where mcast_session.ip = mcast_session1.ip)
对于逻辑的解释,查询可能有助于:

select  host1.name host_name,
       topic1.name topic_name,
       mcast_session1.ip,
       mcast_session1.port,
(select count(*)
          from mcast_session
         where mcast_session.ip = mcast_session1.ip) host_to_topic_registeration,
       (select count(*)
          from topic
         inner join mcast_session
            on topic.mcast_session_id = mcast_session.id
         where mcast_session.ip = mcast_session1.ip
           ) ip_topic_count
  from Subscriber Subscriber1
 inner join host host1
    on host1.id = Subscriber1.Host_Id
 inner join topic topic1
    on topic1.id = Subscriber1.Topic_Id
 inner join mcast_session mcast_session1
    on mcast_session1.id = topic1.mcast_session_id

查看所需结果的另一种方法是应用以下逻辑:

  • 对于每个
    IP
    地址,计算
    主题的总数
  • 对于每个
    主机
    计算按
    IP
    地址分组的
    主题
    广播的总数
  • 所需主机是指每个
    IP
    地址的
    主题数不等于
    IP
    地址总数的主机
  • 以下SA代码应为您提供所需的
    主机
    实例:

    它生成下面的
    SQL
    代码(对于
    SQLite
    ):


    现在,如果要在查询中多次使用同一个表,可以使用。下面的代码将返回元组列表
    (mcasession,NNN)
    ,其中
    NNN
    是具有相同
    IP
    的MCastSession对象数:

    aliased_MCastSession = aliased(MCastSession, name="MCastSession2")
    qry = session.query(\
        MCastSession, \
        func.count(aliased_MCastSession.id).label("number_with_same_ip")).\
    filter(MCastSession.ip == aliased_MCastSession.ip).\
    group_by(MCastSession)
    

    但是我不需要为提出的解决方案这样做,因为我使用了子查询。

    如果有人可以帮助只使用原始SQL查询,这也将有助于两次引用同一个表:
    从my_选项卡中选择一个*作为第一个_引用将my_选项卡作为第一个_引用的第二个_引用加入my_选项卡。ID=second_reference.ID+1
    SELECT  host.id AS host_id, host.name AS host_name
    
    FROM    host
    
    JOIN   (SELECT  host.id AS host_id,
                    mcast_session.ip AS mcast_session_ip,
                    count(topic.id) AS num_topics
            FROM    host
            JOIN    subscriber
                ON  host.id = subscriber.host_id
            JOIN    topic
                ON  topic.id = subscriber.topic_id
            JOIN    mcast_session
                ON  mcast_session.id = topic.mcast_session_id
            GROUP BY host.id, mcast_session.ip
           ) AS host_ip_topics
        ON  host.id = host_ip_topics.host_id
    
    JOIN   (SELECT  mcast_session.ip AS mcast_session_ip,
                    count(topic.id) AS num_topics
            FROM    mcast_session
            JOIN    topic
                ON  mcast_session.id = topic.mcast_session_id
            GROUP BY mcast_session.ip
           ) AS ip_topics
        ON  host_ip_topics.mcast_session_ip = ip_topics.mcast_session_ip
        AND host_ip_topics.num_topics != ip_topics.num_topics
    
    aliased_MCastSession = aliased(MCastSession, name="MCastSession2")
    qry = session.query(\
        MCastSession, \
        func.count(aliased_MCastSession.id).label("number_with_same_ip")).\
    filter(MCastSession.ip == aliased_MCastSession.ip).\
    group_by(MCastSession)